How To Create a Git Branch

How To Create a Git Branch | Learn Git Create New Branch from Current Branch

It is very easy to create and manage branches on Git for developers. As a matter of fact, the flexibility and power of its branching model is the major advantage of git. In Git, branches are a part of your everyday development process. Git branches are effectively a pointer to a snapshot of your modifications.

When you want to add a new feature or fix a bug, you need to create a new branch to encapsulate your changes. In this tutorial, you can get a deeper knowledge of Git branches and easily can understand why they chose to express this behavior in such a non-obvious manner. Also, take a look at the main concept of today’s guide ie., How to create a Git Branch along with Git Commands.

What is a branch?

A branch in Git is simply a lightweight movable pointer to [a commit]. The default branch name in Git is master.

What is Git Branching?

Git branching allows developers to diverge from the production version of code to fix a bug or add a feature. However, developers create branches to work with a copy of the code without changing the current version.

What does the “git branch” command do?

There are a variety of tasks that can perform by using the “git branch” command. They are as follows:

  • creating new local branches
  • deleting existing local or remote branches
  • listing local and/or remote branches
  • listing branches that e.g. haven’t been merged yet

How do I create a new branch based on the current HEAD?

If you want to create a new branch as per your currently checked out (HEAD) branch, just use “git branch” with the name of the new branch as the only parameter shown below:

$ git branch <new-branch>

Creating a Git branch using checkout

The easiest way to create a Git branch is to use the “git checkout” command with the “-b” option for a new branch. Next, you just have to specify the name of the branch you want to create.

$ git checkout -b <branch-name>

As an example, let’s say that you want to create a new Git branch from the master branch named “feature”

To achieve that, you will run the “git checkout” command with the “-b” option and add “feature” as the branch name.

$ git checkout -b feature
Switched to new branch 'feature'

As you can see, by using the “git checkout” command, you are creating a new branch and you are switching to this new branch automatically.

But what if you wanted to create a Git branch without switching to the new branch automatically?

Create Git Branch without switching

In order to create a new Git branch, without switching to this new branch, you have to use the “git branch” command and specify the name of the Git branch to be created.

$ git branch <branch_name>

Later on, you can switch to your new Git branch by using the “git checkout” function.

$ git checkout <branch_name>

Going back to our previous example, let’s say that you want to create a branch named “feature”.

$ git branch feature

You can inspect existing branches by running the “git branch” command with the “-a” option for all branches.

$ git branch -a

Create Git Branch without switching create-branch

Awesome, you have successfully created a new Git branch and you switched to it using the checkout command.

Create Git Branch from Commit

In the last sections, we have seen how you can create a new Git branch from the HEAD commit of the current branch.

In some cases, you want to create a Git branch from a specific commit in your Git history.

To create a Git branch from a commit, use the “git checkout” command with the “-b” option and specify the branch name as well as the commit to creating your branch from.

$ git checkout -b <branch_name> <commit_sha>

Alternatively, you can use the “git branch” command with the branch name and the commit SHA for the new branch.

$ git branch <branch_name> <commit_sha>

Going back to our previous example, let’s say that you want to create a Git branch from a specific commit in your Git history.

To get commits SHA from your history, you have to use the “git log” with the “–oneline” option.

$ git log --oneline --graph

* 9127753 (HEAD -> master) Commit 3
* f2fcb99 Commit 2
* cab6e1b (origin/master) master : initial commit

To create a new Git branch from the second commit (f2fcb99), you would run the following command

$ git checkout -b feature f2fcb99
Switched to a new branch named 'feature'

Using the “git log” command, you can verify that your branch was created from the second commit of your history.

$ git log --oneline --graph

* f2fcb99 (HEAD -> feature) Commit 2
* cab6e1b (origin/master) master : initial commit

Awesome, you have successfully created a new Git branch from a specific commit!

Create Git Branch from Tag

In previous tutorials, we have seen that Git tags are pretty useful: they can be used as reference points in your development.

As a consequence, it can be quite useful to create Git branches from existing tags.

In order to create a new Git branch from a tag, use the “git checkout” command with the “-b” option and specify the branch name as well the tag name for your new branch.

$ git checkout -b <branch_name> <tag_name>

Alternatively, if you don’t want to switch to your new branch, you can use the “git branch” with the branch name and the tag name.

$ git branch <branch_name> <tag_name>

Back to our previous example, let’s say that you want to create a new Git branch from a tag named “v1.0” in your history.

In order to list your existing tags, you can use the “git tag” command. Alternatively, you can use the “git log” command to identify a tag associated with a commit.

$ git tag
v1.0

Now that you have identified your tag, you can create a new branch from it using the “git checkout” command.

$ git checkout -b feature v1.0

Next, you can inspect your Git history in order to make sure that your new branch was indeed created from the tag.

Create Git Branch from Tag create-tag

Alternatively, you could have used the “git branch” in order to create this branch.

$ git branch feature v1.0

How to create a new branch from a remote branch?

If you require to take a remote branch based on your new local branch, you can utilize the “–track” option:

$ git branch --track <new-branch> origin/<base-branch>

On the other hand, you can also use the “checkout” command to perform this. If you want to name the local branch like the remote one, you only have to define the remote branch’s name:

$ git checkout --track origin/<base-branch>

How to create a new branch in a remote repository?

Once you are done with working on a new local branch for some time, you may require to publish it in your remote repository, in order to share it with your team:

$ git push -u origin <local-branch>

The “-u” flag tells Git to establish a “tracking connection”, which will make pushing and pulling much easier in the future.

Note on Ambiguous Names

When you are creating new Git objects (whether they are branches, tags, or commits), you might run into this error

fatal: Ambiguous object name: <object>

So why does this error happens?

This exception occurs whenever two objects are named in the exact same way: a branch and a tag for example.

Whenever you are running a command involving one of those objects, Git can not tell the difference between the two and it returns this exception.

You might run into this error when running the “checkout” command.

If you are creating a new branch from a tag named “v1.0”, but one of your branches is already named “v1.0”, you will be presented with this error

$ git checkout -b feature v1.0
warning: refname 'v1.0' is ambiguous.
warning: refname 'v1.0' is ambiguous.
fatal: Ambiguous object name: 'v1.0'.

In order to solve this issue, you have to specify that your last argument is a tag and not the branch name.

To solve ambiguous notation, simply append the refs notation to the object that is ambiguous

$ git checkout -b feature refs/tags/v1.0
Switched to a new branch 'feature'

Conclusion

In this tutorial, you learned how you can easily create Git branches using the “git checkout” command.

You also learned that you can the “git branch” command if you don’t want to switch automatically to your new branch.

Finally, you have seen more advanced use-cases: creating branches from specific commits or from specific tags in your Git history.

Curious about Git, you can check our latest tutorials:

If you are interested in Git or in software engineering, we have a complete section dedicated to it on the website, so make sure to check it out!

How To Create and Apply Git Patch Files

How To Create and Apply Git Patch Files | Creating & Applying Git Patch Files with Different Git Commands

Patches are a substitute way to exchange code changes and exchanging code via patches is rare. Also, it is a valuable tool in specific circumstances. With creating a patch, you can basically export one or more commits into plain text files, that you can quickly share with someone else for integration.

Traditionally, Git Patch is linked to the Unix Patch command that was utilized in old Unix versions to store differences between files or binaries. In this ultimate tutorial, we are going to talk completely about how to create and apply git patch files and what are the commands used to make it happen. Also, check our Git Commands Tutorial to find all commands in one place.

Create Git Patch Files using git format-patch

To create a Git patch file, you have to use the “git format-patch” command, specify the branch and the target directory where you want your patches to be stored.

$ git format-patch <branch> &lt;options>

So will the format-patch command do when executed?

The “git format-patch” command will check for commits that are in the branch specified but not in the current checked-out branch.

As a consequence, running a “git format-patch” command on your current checkout branch won’t output anything at all.

Also Read: How To Generate Git SSH Keys

Creating a Git patch with git diff

If you want to see commits differences between the target branch and the current checked-out branch, use the “git diff” command and specify the target and the destination branch.

$ git diff --oneline --graph <branch>..<current_branch>

* 391172d (HEAD -> <current_branch>) Commit 2
* 87c800f Commit 1

If you create patches for the destination branch, you will be provided with two separate patch files, one for the first commit and one for the second commit.

For example, let’s say that you have your “master” branch and a “feature” branch that is two commits ahead of your master branch.

When running the “git diff” command, you will be presented with the two commits added to your feature branch.

$ git diff --oneline --graph master..feature

* 391172d (HEAD -> feature) My feature commit 2
* 87c800f My feature commit 1

Now, let’s try creating patch files from commits coming from the master branch.

$ git format-patch master

0001-My-feature-commit-1.patch
0002-My-feature-commit-2.patch

How To Create and Apply Git Patch Files patchfile

You successfully created two patch files using the “git format-patch” command.

Creating Git Patch Files in a Directory

As you probably noticed from the previous section, patch files were created directory in the directory where the command was run.

This might not be the best thing because the patch files will be seen as untracked files by Git.

$ git status

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        0001-My-feature-commit-1.patch
        0002-My-feature-commit-2.patch

In order to create Git patch files in a given directory, use the “git format-patch” command and provide the “-o” option and the target directory.

$ git format-patch <branch> -o <directory>

Back to our previous example, let’s create Git patch files in a directory named “patches”.

This would give us the following command

$ git format-patch master -o patches

patches/0001-My-feature-commit-1.patch
patches/0002-My-feature-commit-2.patch

In this case, we provided the “git format-patch” will a local directory but you can provide any directory on the filesystem out of your Git repository.

Create Git Patch for Specific Commit

In some cases, you are not interested in all the existing differences between the two branches.

You are interested in one or two commits maximum.

You could obviously cherry-pick your Git commits, but we are going to perform the same action using Git patches.

In order to create a Git patch file for a specific commit, use the “git format-patch” command with the “-1” option and the commit SHA.

$ git format-patch -1 <commit_sha>

In order to get the commit SHA, you have to use the “git log” command and look for the corresponding commit SHA.

For example, given the example we just used, let’s inspect the differences between master and feature using the “git log” command.

$ git log master..feature

commit 391172da58dbfa27bc995eda538012ae1fbc5383 (HEAD -> feature)
Author: Bob <test@gmail.com>
Date:   Wed Dec 11 16:24:46 2019 -0500

    My feature commit 2

commit 87c800f87c09c395237afdb45c98c20259c20152
Author: Bob <test@gmail.com>
Date:   Wed Dec 11 16:03:15 2019 -0500

    My feature commit 1

In this case, we are not interested in the second commit (with SHA 391172..) but in the first commit (with SHA 87c800..)

Copy the commit SHA and run the “git format-patch” command again.

You can optionally provide the output directory similarly to the example we provided in the previous section.

$ git format-patch -1 87c800f87c09c395237afdb45c98c20259c20152 -o patches

patches/0001-My-feature-commit-1.patch

Awesome! You successfully created a Git patch file for one single commit on your repository.

Apply Git Patch Files

Now that you have created a patch file from your branch, it is time for you to apply your patch file.

Using git am to Apply a Patch

In order to apply a Git patch file, use the “git am” command and specify the Git patch file to be used.

$ git am <patch_file>

Referring to our previous example, make sure to check out the branch where you want your patch file to be applied.

$ git checkout feature

Switched to branch 'feature'
Your branch is up to date with 'origin/feature'.

Now that you are on your branch, apply your Git patch file with the “git am” command.

$ git am patches/0001-My-feature-commit-1.patch

Applying: My feature commit 1

Now, taking a look at your Git log history, you should see a brand new commit created for your patch operation.

$ git log --oneline --graph

* b1c4c91 (HEAD -> feature) My feature commit 1

When applying a Git patch, Git creates a new commit and starts recording changes from this new commit.

Awesome! You have successfully applied your Git patch file using “git am”.

Git Patch Troubleshooting

In some cases, you might run into errors when trying to apply Git patch files.

Let’s say for example that you have checked out a new branch on your Git repository and tried to apply a Git patch file to this branch.

When applying the Git patch, you are running into those errors.

Git Apply Patch failed: file already exists in Index

This case is easy to solve. You tried to apply a Git patch file that contained file creations (say you created two new files in this patch) but the files are already added into your new branch.

In order to see files already stored in your index, use the “git ls-files” command with the “–stage” option.

$ git ls-files --stage <directory>

100644 eaa5fa8755fc20f08d0b3da347a5d1868404e462 0       file.txt
100644 61780798228d17af2d34fce4cfbdf35556832472 0       file2.txt

If your patch was trying to add the “file” and “file2” files into your index, then it will result in the “file already exists in index” error.

To solve this issue, you can simply ignore the error and skip the patch operation.

To skip a Git patch apply operation and ignore conflicts, use “git am” with the “–skip” option.

$ git am --skip

Git Apply Patch failed: error in file

In some cases, you might run into some “merging” errors that may happen when applying a patch.

This is exactly the same error as when trying to merge one branch with another, Git will essentially fail to automatically merge the two branches.

To solve Git apply merging errors, identify the files that are causing problems, edit them, and run the “git am” command with the “–continue” option.

$ git am --continue

Conclusion

In this tutorial, you learned how you can create Git patch files using the “git format-patch” command. Also, you have understood that it is possible to create Git patch files for single commits and to apply them to the target branch easily using the “git am” command.

How To Setup SSH Keys on GitHub

How To Setup SSH Keys on GitHub | How to Generate SSH Keys Windows & Linux?

Are you using GitHub without setting up SSH Keys? Then, you’re actually missing out on more security and convenience. SSH Keys are the best two authentication methods used on GitHub for secure log-in and address modifications to repositories. Well, this tutorial will help you Setup SSH keys on GitHub easily and in a simpler way for administration.

If you want to check whether you have installed and configured Git on your Windows or Linux OS then make use of this Git Commands tutorial & dig deep into your main requirement.

Why use an SSH Key?

If you want to access your account in a convenient and secured way then it can be possible by using an SSH Key. It’s helpful because you don’t need to memorize a long password. Also, you can get your actual password so brutally long and secure that no human or bot could guess it. The SSH key works as an actual key that only you control.

How to Create SSH keys for Github

Depending on the operating system you are using, there are two ways of creating SSH keys for GitHub.

Do Check: How To Generate Git SSH Keys

Create SSH keys on Linux using ssh-keygen

First of all, let’s have a look at creating SSH keys on Linux operating systems.

To create SSH keys on Linux, use the ssh-keygen command with an RSA algorithm (using the “-t” option)

$ cd ~/.ssh/ && ssh-keygen -t rsa -b 4096 -C "email@example.com"

Note: It is recommended to setup your SSH keys into the .ssh directory of your home directory. Storing them there is more convenient if multiple developers are working on the same repository.

You will be prompted with multiple questions.

You can choose to store your key in a custom file by typing a custom filename.

You can also choose to leave it blank in order for it to be added to the “id_rsa” existing file.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/schkn/.ssh/id_rsa): custom_id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in custom_id_rsa.
Your public key has been saved in custom_id_rsa.pub.
The key fingerprint is:
SHA256:6yBEAZCCAZCAfdeokgo256452574ffaaz+F6dedefr23222CUXTQc email@example.com
The key's randomart image is:
+---[RSA 4096]----+
|@*o+=+.   E..    |
|*+.+o    o .     |
|... =.  ....     |
| . + =. ..o      |
|  . *.o.S  .     |
|   . o.= =  .    |
|    . o o.+.     |
|     . o.oo      |
|        =*o      |
+----[SHA256]-----+

Similarly, you can leave the passphrase blank, otherwise, you will be asked for it as a password when performing operations on your repositories.

The ssh-keygen utility created two files for you :

  • file_id_rsa: the private key used in the SSH authentication process. You should not share this private key by any means.
  • file_id_rsa.pub: the extension gives the hint that this is the public key of your SSH authentication process. This is the key you are going to copy to Github in order to perform operations on your repos.

Configure your SSH keys

If you chose to create the GitHub public key in a separate file, named “custom_id_rsa” for example, you need to configure your SSH client in order to take into account this separate file.

Create a new file named “config” in your .ssh directory and paste the following content into it.

$ sudo nano ~/.ssh/config

Host *
    Hostname github.com
    User git
    IdentityFile ~/.ssh/custom_id_rsa

If you chose a different name, make sure to change the file name in the IdentifyFile line.

Save your file – you should not have to restart your SSH client for the changes to be applied.

Now that your files are ready, you can skip the next section dedicated to Windows hosts and start importing your keys to GitHub.

Create SSH keys on Windows using ssh-keygen

In order to use ssh-keygen on Windows, you need to have the OpenSSH client enabled.

Enabling OpenSSH client on Windows 10

In order to enable the OpenSSH client, you essentially have two options: by using Powershell or by using the graphical interface.

To enable the OpenSSH client via Powershell, use the “Add-WindowsCapability” option and specify the OpenSSH Client.

$ Add-WindowsCapability -Online -Name OpenSSH.Client*

Path          :
Online        : True
RestartNeeded : False
Note : you need to be administrator in order to enable OpenSSH on your computer.

You can also enable the OpenSSH client via the graphical interface :

  • Click on “Start” and search for “Manage Optional Features
  • Click on “Add a Feature
  • Search for OpenSSH and install the OpenSSH client

Installing the OpenSSH client on Windows 10 will allow you to perform multiple commands via the Powershell: ssh-add, ssh-keygen (the one we are interested in), ssh-agent, ssh-keyscan, and the ssh executable.

On Windows, for versions greater than Windows 7, you can use ssh-keygen in order to connect to your remote Git repositories.

Open Powershell and type the following commands

$ ssh-keygen

Enter file in which to save the key (C:\Users\schkn/.ssh/id_rsa): C:\Users\schkn/.ssh/custom_id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in custom_id_rsa.
Your public key has been saved in custom_id_rsa.pub.
The key fingerprint is:
SHA256:WTQ schkn@DESKTOP-PH31996
The key's randomart image is:
+---[RSA 2048]----+
|          o...   |
|         . ...   |
|      . + . .    |
|     E + * =     |
|    .   S B o.   |
|     ..= * .. . .|
|    ..=o* . .o.o.|
|     +oo+*  ..ooo|
|     .=B+.oo..oo |
+----[SHA256]-----+

In the first prompt, you can choose to save your public key in a separate file, but you will need to specify the entire path to the file.

If you chose to create your keys in a separate file, you will need to create a file named “config” into your .ssh directory

Note: The “config” file needs to have no extension at all, it cannot be named “config.txt” for example.

Configure your SSH keys

In order to configure your SSH keys, run the “New-Item” command to create a new file using Powershell.

$ New-Item -Path 'C:/Users/user/.ssh/config' -ItemType File

Note: You have to replace “user” with the actual user using the account

In the configuration file, paste the following content in order to select the correct key when performing Git commands.

Host *
    Hostname github.com
    User git
    IdentityFile ~/.ssh/custom_id_rsa

Save your file, and you should be good to go.

Add SSH key to your GitHub Account

In order to add an SSH key to your GitHub account, head over to the settings of your account and select the “SSH and GPG keys” option in the left menu.

Add SSH key to your GitHub Account ssh-gpg

On the right panel, click on the “New SSH key” button in order to create a new SSH key for Github.

Add SSH key to your GitHub Account ssh-key-create

When clicking on “New SSH key“, you will be asked to choose a name for your key and to paste the public key you saved before.

To get the content of your public key on Linux, use the cat command on your public key file.

$ cat ~/.ssh/custom_id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC+HvRnxwPJyUiUO/UCPKrW6mFPgJF8LxsC2lbBePtn+UDv4Xy+eMJRgG5fbaqy2i0tvP+7T7bjVWtO9AAIlclkIVeu5LmV7RaE8H78VXxGVQLcWXvlS0SGlwIxXXd9hBeGh6qPmrya63Ezrt/J1fNy6Ro9s5+ndLogBG2G0JKdAoytbCIBgPmm6sK9nvv3kHrjSK4S0rRz0nb9oaxCQF6V+T75hPgYp+JMOl8yZZMGLN3GPadE2ye2/lskJXzYjlHyjAE6a0g+vrHmMjOULPUrO+aHEA84f   email@example.com

Note: You can also use the “cat” command in Powershell

Paste the content of your public key to the dedicated key text area on GitHub.

Click on “Add SSH key” in order to complete the process.

A new entry should be added to your SSH keys with the key fingerprint as well as the permissions given by the key (read and write by default)

Congratulations, you have successfully added your SSH keys to GitHub.

In order to validate the entire process, we are going to clone a Git repository to our local system.

This is where you might have authentication failures but multiple solutions will be provided in order to solve those issues.

Test GitHub SSH keys

In order to test our GitHub SSH keys, let’s try to clone one of our repositories on our local server.

In order to find the SSH URL, you have to use, head over to your repository and click on the “Clone or download” green button.

Make sure that you are using the SSH method by clicking on “Use SSH” if not already selected.

Test GitHub SSH keys clone-download

To clone the Github repository, use the “git clone” command with the URL provided in the previous box.

$ git clone git@github.com:SCHKN/private-repo.git

Cloning into 'private-repo'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

Awesome!

The repository was correctly fetched from GitHub and you can start working on the codebase.

Troubleshooting

In some cases, you may not be able to fetch your repositories from GitHub when setting up SSH authentication.

You will probably get the following error when performing simple git commands on your client

git@github.com: Permission denied (publickey)

This may be happening because of multiple reasons :

  • Your public key is not correctly set on GitHub

Make sure in your account settings that your public key is set and that the permissions are also set properly.

  • You are using a different file from the “id_rsa” default file to store your keys and you did not create the “config” file into your .ssh directory.

Refer to the previous sections to set your “config” file properly.

  • You are not using the correct URL in order to fetch your repositories.

Make sure that you are executing your commands as the “git” user and not with the GitHub username you are using on the website.

$ git clone git@github.com:SCHKN/private-repo.git   <--- Correct

$ git clone user@github.com:SCHKN/private-repo.git  <--- Incorrect

Conclusion

In this tutorial, you learned how you can set up SSH keys for Github accounts and how you will have to configure them to use custom keys.

If you are curious about Git or about software engineering in general, we have a complete section dedicated to it on the website, so make sure to read our latest guides.

How To Create Git Tags

How To Create Git Tags | Types of Tags in Git | Creating Git Tags with Examples

In Git History, tags are ref’s that point to specific points. Generally, Tagging is done to capture a point in history that is utilized for a marked version release (i.e. v1.0.1). A tag is like a branch that doesn’t change. If your want to have a reference to a given release of your software should create a new tag.

Are you new to Git and not familiar with the Git tags & Git Commands? Check out this entire tutorial and learn How to Create Git Tags easily along with naming the Git tags following the best practices of “Semantic Versioning”.

How do you Create Git Tag?

In order to create a new tag, you have to use the “git tag” command and specify the tag name that you want to create.

$ git tag <tag_name>

As an example, let’s say that you want to create a new tag on the latest commit of your master branch.

To achieve that, execute the “git tag” command and specify the tag name.

$ git tag v2.0

Usually, you want to name your tag following the successive versions of your software.

Using this command, the latest commit (also called HEAD) of your current branch will be tagged.

Create Git Tag create-tag-1

To verify that your Git tag was successfully created, you can run the “git tag” command to list your existing tags.

$ git tag

v1.0
v2.0

Good job!

You have successfully created a tag on Git.

Create Tag with Message

Creating tags is great but you will need to add a description to your tag in order for other contributors to understand why you created it.

You would not create a commit without a commit message, you would not create a Git tag without a message.

To create a Git tag with a message, use the “git tag” command with the “-a” option for “annotated” and the “-m” option for message.

$ git tag -a <tag_name> -m "message"

Note: If you don’t provide the “-m” option, your default text editor will open in order for you to type the tag message.

As an example, let’s say that you want to create a new annotated tag on your master branch with the message “New release for v3.0”

To achieve that, you would run the following command

$ git tag -a v3.0 -m "New release for v3.0"

You can verify that your Git tag was successfully created by running the “git tag” command with the “-n” option.

$ git tag -n

Create Tag with Message create-tag-2

Git Tag Types

As of now we know we have learned about git tag and how to create easily, let’s discuss the type of tags that supported by git. You can have two types of Git tags, one is Lightweight Tags and another is Annotated Tags.

Lightweight Tags

As the name suggests Lightweight Tags is the simpler and trimmed down version of creating a tag without any meta-information about the tag. Here is the syntax of the Git Lightweight tags.

$ git tag <tag_name>

Annotation Tags

Annotation Tags is a process of creating a Git tag with some extra meta information. To create an annotation tag you just need to add “-a” with the git tag command and “-m” to specify the message.

$ git tag -a v1.0 -m “Release v1.0 create.”

Now, you can apply the “git show” command to view all the data attached with the tag we simply created with annotation.

Naming tags with Semantic Versioning

When naming tags, the Git CLI does not put any constraints on the name of your Git tag.

However, there are some best practices when it comes to naming Git tags: using semantic versioning.

Semantic versioning is quite easy to understand: you want to name tags as versions of your software in the form of

v<major>.<minor>.<patch>

Where

  • major: is a version number where you introduced breaking modifications (modifications of your new version are NOT compatible with previous versions);
  • minor: is a version number that is compatible with previous versions;
  • patch: is an increment for a bug fix or a patch fix done on your software.

For example, let’s say that you are currently working on version 1.0.0 of your software.

In your latest commit, you introduced a code-breaking change, as a consequence you are going to increment the major version number.

$ git tag v2.0.0

Push your created tags

By default, the “git push” command does not automatically push your tags to your remote repository.

To push your newly created tags, use the “git push” command and specify the “–tags” to explicitly push tags to your remote Git repository.

$ git push --tags

For example, given the tags that you created in the previous section, you would get the following output

$ git push --tags

To <user>/<repository>.git
* [new tag]         v1.0 -> v1.0
* [new tag]         v2.0 -> v2.0

Great, now your tags are pushed to your remote repository and your colleagues can start fetching it.

Create Git Tag for Commit

In some cases, you may want to create a Git tag for a specific commit of your Git history.

In order to create a Git tag for a specific commit, use the “git tag” command with the tag name and the commit SHA for the tag to be created.

$ git tag <tag_name> <commit_sha>

If you want to create an annotated tag for a specific commit, you can use the “-a” and “-m” options we described in the previous section.

$ git tag -a <tag_name> <commit_sha> -m "message"

As an example, let’s say that you want to create an annotated commit for the first commit of your Git history.

First, list the commits SHA by using the “git log” command with the “–oneline” option to get short commits SHA.

$ git log --oneline

9127753 (HEAD -> master) Commit 3
f2fcb99 (feature) Commit 2
cab6e1b (origin/master) master : initial commit

In order to create an annotated tag for the first commit in your Git history, you would execute the following command

$ git tag -a v1.0 cab6e1b -m "Tagged the first commit with v1.0"

Next, run the “git log” command again to make sure that your commit was correctly tagged.

$ git log --oneline

9127753 (HEAD -> master) Commit 3
f2fcb99 (feature) Commit 2
cab6e1b (tag: v1.0, origin/master) master : initial commit

Awesome, you have successfully created a tag for a specific commit in your Git history.

Create Tag For Last Commit

If you want to create a Git tag from the last commit, there is a shorter syntax that you can use: the HEAD syntax.

In order to create a Git tag for the last commit of your current checked-out branch, use the “git tag” command with the tag name and specify “HEAD” as the commit to create the tag from.

$ git tag <tag_name> HEAD   (for the last commit)

$ git tag <tag_name> HEAD~1  (for the commit before HEAD)

$ git tag <tag_name> HEAD~1  (for two commits before HEAD)

Similarly, if you want your tag to be annotated, you can still use the “-a” and “-m” options to annotate your tag.

$ git tag -a <tag_name> HEAD -m "message"

Like in the previous sections, you can verify that your tag was successfully created by running the “git tag” command with the “-n” option.

$ git tag -n

v1.0
v2.0
v3.0

Congratulations, you have successfully created a new tag for the last commit of your repository.

Conclusion

In this tutorial, you learned how you can easily create Git tags for your projects.

You also discovered advanced usages of tags with annotated messages but also about naming your git tags correctly using semantic versioning.

If you are interested in Git, you should have a look at our previous tutorials :

Also, if you are passionate about software engineering, we have a complete section dedicated to it on the website, so make sure to check it out!

How To Add Swap Space on Debian 10 Buster

This tutorial focuses on how to create swap space on Debian 10 via a swap file or a swap partition on your hard drive.

On a Linux system, it is very common to run out of memory, because you run too many programs, or because you run programs that are consuming too much memory.

As a consequence, if your RAM is full, you won’t be able to launch new programs on your computer.

You will have to manually shut down programs or tweak them to consume less memory.

There is however another way to virtually increase your memory : by using swap space.

In this tutorial, we are going to see how you can add swap space on Debian 10, either by creating a swap file or by creating a disk partition dedicated to swap.

Looking to add swap space on CentOS 8?

What is Swap Space on Debian?

Swap space is a space allocated to handle additional programs running when your RAM memory is full.

Let’s say that you have 4 GBs of RAM on your computer, and that 3 programs are already taking 3.5 GBs out of the 4 available.

What is Swap Space on Debian ram-1

If you are trying to run a program that is taking 1 GB on normal usage, you won’t be able to do it as you don’t have the space necessary for the program.

You could buy some RAM (which is expensive), or you could choose to create some swap space on your host.

When running your 1 GB program, your operating system (Linux here) will “move” or “swap” one of the programs to a dedicated part of your hard drive (your swap partition) and run your 1 GB program on the newly allocated space.

What is Swap Space on Debian ram-2

As you can imagine, the OS can switch programs from swap to RAM and vice versa.

The threshold to determine when programs should be switched from RAM to Swap is called the swappiness, but configuring ths swappiness will be reserved for another tutorial.

Now that you have some basics on what the swap space is and how the swap space works on Linux, let’s see on you can create some swap space on Debian 10.

Prerequisites

Sudo privileges

In order to add swap space on Debian 10 Buster, you need to have sudo privileges on your host.

Make sure this is the case by running the following command

$ sudo -v

If you are not getting any errors messages, you are good to go.

Checking existing swap partitions

In order to see existing swap partitions available on your host, run the following command

$ sudo swapon --show

If a partition is already existing, you should get at least one line as a result.

swap-show

As you can see, I already own a swap partition on my sda drive of size 8 GB.

As the current memory on my computer is sufficient, my host is not using swap at the moment.

If no swap spaces are configured on your system, this is the output that you should expect.

swap-show-2

Add Swap Space with a swap file

The first method to add swap space on Debian is to use a dedicated swap file.

Many tutorials are not specifying this detail, but swap files cannot contain any holes at all.

It means that you should not use the cp command to create your swap file.

It is also not recommended to use the fallocate commands on file systems that support preallocated files such as XFS and ext4.

As a consequence, you are going to use the dd command in order to add swap space on Debian.

add-swap-space-dd

In this case, we are going to create a 2 GB swap file.

Note : there are no performance improvements in using a swap file rather than creating a file partition. Swap files are just easier to manage because the file size can be easily adjusted. Changing the partition size for swap can be trickier than changing the file size.

a – Create a swapfile using dd

To add swap space, run the following command

$ sudo dd if=/dev/zero of=swapfile bs=1MiB count=$((2*2014))

Make sure that your swap file was created by issuing the following command.

$ ls -l swapfile

swap-2

b – Secure your swapfile with permissions

Swap files are only used by the operating system for memory optimization purposes.

As a consequence, it should not be modified by any users except for the root user.

Change the file permissions of your swapfile.

$ sudo chmod 600 /swapfile

c – Enable your swapfile

Now that your swapfile is secure, it is time to activate your swap space.

To enable swap space on Debian 10, run the following command.

$ sudo mkswap /swapfile

This is going to set the file as a swap file, setting the correct headers for the swapon binary.

mkswap

Now that the swapspace is correctly set, you can enable it.

$ sudo swapon /swapfile

To verify that your swap space is active, you can run the initial command with the –show flag.

$ sudo swapon --show

swapon-success

d – Make your swap space permanent

Similarly to the creation of filesystems, changes won’t be made permanent if you don’t append some changes to the fstab file.

If you leave it this way, your swap space will be erased at the next host reboot.

To make your swap space permanent, edit the /etc/fstab file and paste the following changes.

$ cd /etc/
$ sudo nano fstab

/swapfile none swap defaults 0 0

This configuration specifies that :

  • /swapfile: the name of the “swap filesystem” we are creating;
  • none: there is mount point for this filesystem
  • swap: the filesystem type used
  • defaults: the filesystem options, set as default for this example
  • 0: the dump option for the filesystem, as well as the pass option.

Save your file, and restart your changes to make sure that the changes are still effective.

$ sudo reboot
$ sudo swapon --show

Congratulations!

You successfully created swap space on Debian 10 using a swap file.

Add Swap Space with a swap partition

Another way to add swap space on Debian is to create a dedicated swap partition.

If you run the initial Debian 10 installation, there is a high chance that some swap partition is already created on your system.

However for this tutorial, we are going to start from scratch and create our own swap partition.

a – Create a swap space partition with fdisk

To have a look at the existing partitions on your host, run the following command

$ sudo fdisk -l

list-partition-1

As you can see, I already own a ext4 primary partition and a second partition that is not currently used.

We are going to add a swap partition as an extended or logical partition on sda.

Run the fdisk utility, and create a new partition on the hard drive that you want (sda in my case)

$ sudo fdisk /dev/sda

Welcome to fdisk (util-linux 2.30.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): n

Run the “n” command to add a new partition to your disk.

Note : if your host is running out of primary partitions, you can add swap space within an extended partition.
All space for primary partitions is in use
Adding logical partition 5
First sector (48291898-65062911, default 48291840):

You can leave the first sector option as default by just pressing Enter.

On the next prompt, specify the size of your swap partition. In this case, I am going to use 2 GiB again.

Last sector, +/-sectors or +/-size{K,M,G,T,P} : +2G

Created a new partition 5 of type 'Linux' and of size 2 GiB.

As you can see, partitions are created with the Linux partition type by default.

This is not what we want, since we want to have a swap partition on our drive.

To change the partition type, run the “t” command in fdisk.

Command (m for help): t
Partition number (1,2,5, default 5): 5
Hex code (type L to list all codes): 82

On Linux, swap partitions have the partition type ID 82 in fdisk.

Hit Enter, and make sure that your partition type was correctly changed.

Changed type of partition 'Linux' to 'Linux swap / Solaris'

Don’t forget to write your changes to disk as fdisk does not directly write to disk unless you ask it do it.

To write on disk, run the “w” command in fdisk.

The partition table has been altered
Syncing disks.

Make sure that your swap partition was correctly added by running the fdisk command again.

list-partition-2

Now that your swap partition is created, it is time to enable it on our Debian 10 host.

b – Enabling your swap partition

First, make sure to run the mkswap for the swap headers to be correctly set on your partition.

$ sudo mkswap /dev/sda5

mkswap-2
Now that your headers are set, run the swapon command.

$ sudo swapon /dev/sda5

Similarly to the other method, make sure that your swap space was correctly created.

$ sudo swapon --show

swapon-show-2

c – Make your swap space permanent

In order to make your swap space permanent, it needs to be added to the fstab file.

First of all, get the UUID for your newly created partition.

$ sudo blkid

c – Make your swap space permanent blkid

Copy the UUID value, and edit your fstab to append the following changes.

$ sudo nano /etc/fstab

UUID=4c46c5af-3530-486b-aabe-abca2543edca   none   swap  defaults   0   0

Save your file, and restart your system to make sure that your changes are permanent.

$ sudo reboot
$ sudo swapon --show

swapon-show-3

Congratulations, you correctly created a swap partition using fdisk on Debian 10 Buster.

Remove swap partition on Debian

Removing swap partitions on Debian is pretty straightforward : first you need to use the command “swapoff” on the swap partition you are trying to remove.

If you are not sure about your current existing partitions, run a simple “blkid” command.

$ blkid 

$ sudo swapon /dev/sda5

Finally, edit your fstab and remove the entry associated with the swap partition.

$ sudo nano fstab

UUID=4c46c5af-3530-486b-aabe-abca2543edca   none   swap  defaults   0   0     <--- To be removed.

Troubleshooting

When adding swap space on Debian 10 Buster, you may run into the following error.

Troubleshooting

swapon: /swapfile: read swap header failed.

This error is happening when you don’t run the mkswap command before running the swapon command.

As a reminder, mkswap sets the header for the file or the partition to be used as swap space.

If you forget to run the mkswap command, Linux won’t be able to assign it as swap space on your host.

Location of swap file on Linux

By default, swap files are located into the “/proc/swaps” directory of your system.

~$ cat /proc/swaps
Filename                Type        Size    Used    Priority
/swapfile               file        1025101 0       -1

From there, you know that your swap file is located at your root directory.

Another way to get the location of your swap file is to inspect the fstab file.

$ cat /etc/fstab

/swapfile    none     swap    sw     0       0

Conclusion

Today, you learnt that there are two ways to add swap space on a Debian 10 host, by creating a swap file or by creating a swap partition with fdisk.

Source Command on Linux Explained

The source command on Linux is a pretty popular function run by system administrators daily.

But what is the function of the source command?

Used to refresh the current shell environment, the source command can also be used in order to import functions into other bash scripts or to run scripts into the current shell environment.

In today’s tutorial, we are going to see how the source command should be used on Linux.

The commands will be executed in a Debian 10 environment with GNOME, but they will work for every distribution.

Source command internals

Before starting, it is important to have a complete understanding of what environment and shell variables are.

By default, on Linux, your system already owns a couple of environment variables to store various information such as the shell to use, your hostname or your current username.

Environment variables are initialized by the system and are inherited by all processes on the system. As a consequence, when you are running a shell instance, you are to get the value of environment variables on your system.

$ echo $USER
devconnected

On the other hand, shell variables are variables declared within the context of a shell instance and they are not shared with other shells or with child processes.

$ VARIABLE=devconnected
$ echo $VARIABLE
devconnected

On Linux, when you execute a script, it is most likely executed in a subshell.

As a consequence, you won’t be able to have the variables defined in your first shell running in the script, they simply don’t share the same environment.

This is what the source command solves.

The source command is used in order to evaluate the file passed as an argument in the context of the current execution. Shortened as ‘.’, the source command is mostly used in the context of shells run in terminal windows.

$ source filename [arguments]

Note that when arguments are provided, they are set as positional parameters for the script specified.

Note : the source documentation is located inside the bash documentation. To read it, type “man bash” and search for the source command paragraph.

Source command internals source-documentation

Source to update your current shell environment (.bashrc)

One of the main reasons to use source is to refresh the current shell environment by running the bashrc file.

As a reminder, .bashrc is a script file executed whenever you launch an interactive shell instance.

It is defined on a per-user basis and it is located in your home directory.

Let’s say for example that you want to add a new alias to your shell environment.

Open your .bashrc file and a new entry to it.

alias ll='ls -l'

Now try to run your new alias command directly in the terminal.

alias

As you can see, the changes were not directly applied in your current environment.

For the changes to be applied, run the source command with the .bashrc file as an argument.

$ source ~/.bashrc

An alternative way to do it is to run it with the dot syntax

$ . ~/.bashrc

If you try to execute your alias again, you should be able to run it

alias-working

Source to execute a script in the current context

As explained before, the source command can be used to execute a script in the context of the current environment.

To illustrate this point, let’s define a local shell variable in your current shell environment.

$ VARIABLE=devconnected

Now, create a new script and paste the following content in it

#!/bin/bash

echo $VARIABLE
echo $LOGNAME

The VARIABLE variable represents the local shell variable we created before and the LOGNAME variable is an environment variable on your host.

Save your script and give execute permissions to your newly created script (you will need sudo privileges to execute this command)

$ sudo chmod ugo+x <script>

If you try to execute the script, you should see the following result

logname-1

As you can see, the $VARIABLE local variable was not printed to the standard output.

This is because the script was executed in a subshell having its own set of local variables. The environment variable was printed however.

In order to execute this script in the context of our current shell, we are going to use the source command.

source-script

As you can see, in this case, the $VARIABLE variable was correctly printed to the standard output.

Source to import a script function

One of the great features of the source command is to update a script function, allowing a greater reusability of your existing shell functions.

To illustrate this point, let’s take the example of a function that prints the current user to the standard output.

Create a new script file and paste the following content inside.

$ nano script

#!/bin/bash
# Print the current user to the standard output
printUser() {
   echo $USER
}

Create another script and use the source function in order to import your printUser function.

$ nano import-script

#!/bin/bash
source ./script
printUser

Assign the correct permissions to the file you want to execute. You don’t need to have the execute permissions for the file containing the function you want to import.

$ sudo chmod u+x import-script
$ ./import-script

This is what you should see on your screen.

source-function

As you can see, the function was correctly imported and executed, printing the name of the current user of my host.

Source to read variables from a file

Another great usage of the source command on Linux is to read variables from a file.

Let’s say for example that you have a file with the following content in a file named “variables

NAME=devconnected
WEBSITE=devconnected.com
DESCRIPTION="best educational website online"

In another script file, you would be able to use those variables by using the source command to read variables.

Create a script and paste the following content in it.

$ nano variable-script

#!/bin/bash
source ./variables
echo $NAME is a website located at $WEBSITE and it is probably the $DESCRIPTION

source-variable

Troubleshooting

In some cases, you may run into errors when trying to source your files using the source command.

Here is a list of the common errors when trying to source files.

Source command not found on Linux

In some cases, you may run into this error

$ source: command not found

Or using sudo, you might also have a source command not found error.

$ sudo: source: command not found

The easy fix here is to execute the command as the root user by using “su”.

$ sudo -s
$ source .bashrc

Note that you can also use the “dot syntax” which is an equivalent to the source command.

$ . .bashrc

Conclusion

In today’s tutorial, you learnt what is the source command on Linux and how you can use to execute scripts in the context of the current environment.

You also learnt that it can be used to import functions or variables from a simple file to a script file.

If you want more tutorials related to Linux system administration, we have a complete category dedicated to it on devconnected. Click on the image below to read them.

How To Change User Password on Debian 10

On Debian 10, users are able to change their password pretty easily.

It is also possible, if you have sudo rights, to change user passwords as well as to define rules for password change on the host.

In this tutorial, we are going to see how you can change the user password on Debian 10 through the command-line and the user interface if you are using a GNOME desktop.

Change User Password using passwd

The first way to change the user password is to use the passwd command.

$ passwd

Changing password for devconnected.
Current password:
New password:
Retype new password:
passwd: password updated successfully

If you type the same password, you are going to have a warning message saying

Password unchanged

Change Another User’s Password with passwd

Before running the passwd command, make sure that you have sudo rights on your Debian 10 host.

To check sudo rights quickly, run the sudo command and make sure that you have error messages.

$ sudo -v

If you have sudo rights, you can run the passwd command.

Note: when updating another’s user account, you are not forced to know the current user password. It is very handy if you want to restrict the access to a user.

$ sudo passwd <user>

New password:
Retype new password:
passwd: password updated successfully

Delete Another User’s Password with passwd

Sometimes you want to reset the user password, maybe because it has lost it or because the password has been compromised.

You can set the password for the user, or you can delete the existing password to make the account passwordless.

To delete another user’s password, run the following command

$ sudo passwd -d <user>
passwd: password expiry information changed

Now when logging via the GNOME user interface, you won’t be prompted with a password. The account will automatically be logged in.

Note: deleting a user password must be done under rare circumstances and the account should be updated quickly to set a secure and long password.

User data might be compromised if no passwords are set for the account.

Expire Another User’s Password with passwd

When setting a passwd on Debian, the password will never expire by default.

But sometimes, because you want to apply correct password policies, you may want to set an expiration time or to expire some accounts after a given time.

To expire another user’s password on Debian, run the following command

$ sudo passwd --expire <user>
passwd: password expiry information changed

Now when logging on the other user account, it should be prompted to change its password.

Expire Another User’s Password with passwd expire-user-password

Change your password on the GNOME desktop

If you are using Debian 10 with a GNOME desktop, you can modify your password via the user interface.

System administrators tend to use the command line to perform administrative operations, but nothing forces you to do it this way.

1. In the Activities search box, type “Settings” and open it.

Add a user using the GNOME desktop settings

2. In the Settings window, choose the “Details” option.

Change your password on the GNOME desktop details-1

3. Choose the “Users” option, and find the user you want to modify.

Change your password on the GNOME desktop users-window

4. Click on the password field. Specify your old password and change your password to a secure one.

Change your password on the GNOME desktop change-password-debian

Click on “Change” and your password should be changed. Make sure to log again to test your new password.

Troubleshooting

In some cases, you may run into some errors while changing your password on Debian 10.

Here is the list of the most common errors and their solutions.

Default root password on Debian 10

By default, there is no default password for the root account on Debian 10.

This is because the root account is locked by default and setting a root password will unlock the account.

If you forgot your root password, you will have to reset it by rebooting and starting a bash shell into the GRUB.

Forgotten password on Debian 10

If you forgot your password on Debian, you will have to reset your password using the passwd command.

If you are not the system administrator, you have to ask the admin to run the passwd command in order to reset your password and make it expire immediately.

If you are the system administrator, you can run the passwd yourself.

$ sudo passwd <user>

If you remember the root password, connect as root and change the user password over there.

$ su -

$ passwd <user>

Conclusion

With this tutorial, you learnt how to change user password on Debian 10 Buster.

Another method to authenticate on a server is to use SSH keys. Make sure to check this article if you are interested in logging with SSH keys on Debian 10.

I hope that you learnt something new today.

Until then, have fun, as always.

How To Git Stash Changes

How To Git Stash Changes | Learn Git Stash Apply, Pop, Clear, Show, Drop

Guys who are new to Git should aware of the git stash command as it is the most important command in Git. It is performed to protect all the changes made with the current working directory and to go back to the last commit done on the branch (also known as HEAD).

In this tutorial, we guys will definitely come to know about git stash commands and how to do git stash changes in practical cases. Just make use of the available links and jump into the exact stuff you required to learn about Git stashing.

Introduction to Git Stash

In some cases, you need to change the branches however you are operating an unfinished part of your current project. In that situation, you don’t want to do a commit to half-done work. Here, Git stashing permits you to do so. The git stash command allows you to change branches without committing the current branch.

Also Check: Git Commands

The following image shows the properties and role of stashing concerning the repository and working directory.

git stash image

Usually, the meaning of stash is “store something safely in a hidden place.” The sense in Git is also the same for stash; Git temporarily saves your data safely without committing.

What is Stashing?

Stashing takes the messy state of your working directory, and temporarily saves it for further use. Several options are available with git stash. Some of the helpful options are provided here:

  • Git stash
  • Git stash save
  • Git stash list
  • Git stash apply
  • Git stash changes
  • Git stash pop
  • Git stash drop
  • Git stash clear
  • Git stash branch

Stashing changes come with a special set of Git commands intended to createdelete and apply stashes at will.

Do Check: How To Set Upstream Branch on Git

Create a Git stash

The easiest way to create a git stash is to simply run the “git stash” command without any parameters.

$ git stash

As a consequence, all the changes staged for commit in your current working directory will be saved on the side for later use.

$ git stash
Saved working directory and index state WIP on branch1: 808b598 Initial commit

As you can see, my working directory as well as my index was saved for the “branch1” which is the current name of my branch.

After the colons, you can see the hash of the HEAD commit as well as the commit message: this is the name of your stash.

In this case, no names were assigned to our stash which might not be very handy if you want to pop your stash later on.

Create a Git stash with a name

In order to create a git stash with a name, use the “save” command and specify the name of your stash.

$ git stash save "my_stash_name"

Back to the example, we gave before on the branch named “branch1”, we would run

$ git stash save "modified README.md"
Saved working directory and index state On branch1: modified README.md

Now, Git did not provide a default name (made by the last HEAD commit message) but it assigned a custom name to it.

Alternatively, you can use the “git stash push” command in order to create a stash with a name.

$ git stash push -m "modified the README.md" again
Saved working directory and index state On branch1: modified again the READ.me

Stashing your work

The git stash command takes your uncommitted changes (both staged and unstaged), saves them away for later use, and then reverts them from your working copy. For instance:

$ git status
On branch main
Changes to be committed:
   new file: style.css
Changes not staged for commit:
   modified: index.html

$ git stash
Saved working directory and index state WIP on main: 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage

$ git status
On branch main
nothing to commit, working tree clean

Currently, you’re free to make changes, create new commits, switch branches, and perform any other Git operations; then come back and re-apply your stash when you’re ready.

Remark that the stash is local to your Git repository; stashes are not given to the server when you push.

Stash a specific file

Using the previous commands, you have stashed all the tracked files in your current working directory.

In some cases, you may want to stash a specific file in order to retrieve it later on.

To stash a specific file, use the “git stash push” command and specify the file you want to stash.

$ git stash push -m "message" <file>

For example, in order to stash the “README.md” file in our current working directory but keep changes done to the other files, we would run

$ git stash push -m "modified the README.md" README.md
Saved working directory and index state On branch1: modified README.md

However, the other tracked files that may be modified in your current working directory are untouched.

Stash untracked files

As you probably noticed before when creating stashes, stash only saves tracked files of your working directory by default.

But what if you wanted to stash untracked files of your current working directory?

In order to stash untracked files, add the “–include-untracked” option to your “git stash” initial command.

Alternatively, you can simply use the “-u” which is equivalent to the untracked longer version.

$ git stash --include-untracked
Saved working directory and index state WIP on branch1: 808b598 Initial commit

$ git stash -u

Specific Git Stash Branch

In some cases, you may want to stash your current changes into a specific branch.

Let’s say for example that you worked on the “master” branch for modifications, but you decide that your work may need a specific branch for integration.

This can be done with the “git stash branch” command.

$ git stash branch <branch_name>

$ git stash branch <branch_name> stash@{stash_index}

Let’s say for example that you want to stash your current changes in a branch named “branch1”, you would execute.

$ git stash branch branch1 stash@{0}

Switched to a new branch 'branch1'
On branch branch5
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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
Dropped stash@{0} (8bf64dd0e0045069bf3b3e7d9e34f5e5227aefa7)

As you can see, the stash is dropped at the end of the process, essentially removing it completely from the stash stack.

Git Stash Changes

We can trace the stashes and their changes. To view & understand the changes in the file before stash and after stash operation, execute the below command:

Syntax:

$ git stash show

This command will help you display the file that is stashed and changes made on them. Take a look at the following output:

git stash changes output

This result explains that there are two files that are stashed, and performed two insertions on them.

Tracking Git Stash Changes

Also, we can precisely track what changes are performed on the file. To show the changed content of the file, execute the below command:

Syntax:

$ git stash show -p

Here, -p stands for the partial stash. The given syntax will display the edited files and content, view the below output:

git stash track

The above output is bestowing the file name with changed content. It runs as same as the git diff command and also gives the exact output.

Also, look at the below video tutorial to gain more knowledge on how to git stash changes:

List Git stashes

Now that you have created some stashes, it is time for you to list the stashes that you just created.

In order to list Git stashes, use the “git stash list” command.

$ git stash list

stash@{0}: WIP on branch1: 808b598 Initial commit
stash@{1}: On branch1: modified README.md
stash@{2}: On branch1: modified again the READ.me

As you can see, stashes are given an index starting at zero.

When creating new stashes, items are added to the stack meaning that the most recent stash has the index 0 while the oldest stash is at the bottom of the stack.

This is closely related to the concept of a stack in software engineering. A link to an in-depth article is included if you are curious about stacks.

Apply Git stashes

Now that you have saved your Git stashes on the side, you might want to “take them out from the stack” and apply them to your current working directory.

In order to apply your Git stash to your current working directory, use the “git stash apply” command and specify the stash you want to apply.

If you don’t specify any arguments to the apply command, the top of the stack will be applied.

$ git stash apply stash@{stash_index}

$ git stash apply (shortcut for git stash apply stash@{0})

For example, in order to apply the changes done in the stash with index 1, we would run

$ git stash apply stash@{1}

Already up to date!
On branch branch1
Your branch is up to date with 'origin/branch1'.

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:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        file

By default, the stash applies command will list your current working directory after applying the corresponding stashes.

Now if you were to list your stashes, you would notice that applying your stash did not delete or remove the stash from the list.

$ git stash list

stash@{0}: WIP on branch1: 808b598 Initial commit
stash@{1}: On branch1: modified README.md
stash@{2}: On branch1: modified again the READ.me

If you want your stashes to be removed after applying them, you need to use the “git stash pop” command.

Pop Git stashes

So what is the difference between git stash pop and git stash apply?

The main difference is in the fact that the “git stash pop” applies your changes to your current working directory but it also deletes the stash from the stash stack.

To pop Git stashes, simply use the “git stash pop” command and specify the stash index you want to pop.

$ git stash pop stash@{stash_index}

Back to our previous stash example, this would give us

$ git stash pop stash@{1}

Already up to date!
On branch branch1
Your branch is up to date with 'origin/branch1'.

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:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        file

Dropped stash@{1} (1adaf79224dca78aa6568b1e8154cbc4f747042f)

See the difference in the last line of the example?

The stash was dropped and removed from the stack.

Show Git stash differences

When you create a stash, it is most likely to perform some commits before going back to your stashed content.

As a consequence, you may want to see the differences between your stash and the most recent commit of your branch (also called HEAD)

To show the differences between a stash and the most recent commit, use the “git stash show” command.

$ git stash show stash@{stash_index}

README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

As a consequence, you will be listed with the differences between files, the insertions, and the deletions done.

To see all the differences including content, add the “-p” option.

$ git stash show -p stash@{stash_index}

diff --git a/README.md b/README.md
index f25b874..1088f9a 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
-# private-repo
\ No newline at end of file
+The file was modified!

Drop Git stashes

In some cases, you may want to delete a Git stash entry from your stack.

In order to drop stashes, you have two options: with a drop or clear.

If you want to drop a specific stash from your stack, use the drop option and specify the stash index.

$ git stash drop stash@{stash_index}

For example, in order to delete stash with an index 1 from the previous example, you would run

$ git stash drop stash@{1}
Dropped stash@{1} (c11c6ae6c347d23dff8fbbf79d54a9e6e2e79b1c)

Drop all stashes using clear

If you want to delete all the Git stashes in your stack, you have to use the clear command.

$ git stash clear

Make sure that all your stashes were deleted with the list command.

$ git stash list

Conclusion

In this tutorial, you acquired basic knowledge about git stash such as how you can create stashes, delete stashes, and pop them in order to recover your work.

Git stash is pretty useful, but there are many other commands that you may find useful when using Git :

  • You can learn how to set the upstream branch on Git;
  • If you are just starting out, you can start by cloning repositories into your system.

If you are interested in software engineering, we have a complete section dedicated to it on the website, so make sure to check it out!

How To Unstage Files on Git | Different Ways to Unstage Files in Git

As developers, using & working with Git is mandatory. Git Users every time deals with many files in the local repository. If any user accidentally added any file to your Git then you can remove it from your index by performing the unstage files on Git. Unstaging file is very beneficial, it can be used to separate files in different commits or to do work on some other modifications.

If you are a beginner, then take help from the Junos Notes provided Git Commands Tutorial. However, this tutorial is completely on How to unstage files on Git and it addresses various methods to unstage all files or particular files or committed files elaborately in the below modules.

Prerequisites

  • Firstly, Installation of Git is the required
  • A Git project
  • Create a local and remote repository
  • A terminal window/command line
    • Linux: Activities > Search > Terminal
    • Windows: right-click Start > Command prompt (or Windows PowerShell)

Unstage a File in Git

In Git, unstaging a file can be done in two ways.

1) git rm –cached <file-name>
2) git reset Head <file-name>

1. Unstage Files using git `rm` command

One of the methods to unstage git files is using the ‘rm’ command. It can be used in two ways:

1) On the brand new file which is not on Github.
2) On the existing file which exists on Github.

Let’s check the process of using the git rm command in both scenarios.

Case 1: rm –cached on new file which is not committed.

rm –cached <brand-new-file-name> is useful to remove only the file(s) from the staging area where this file is not available on GitHub ever. After executing this command, the file rests in the local machine, it just unstaged from the staging area.

Example:

$ git add filetwo.txt
$ git status

On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: filetwo.txt

$ git rm --cached filetwo.txt
$ git status

On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
filetwo.txt
nothing added to commit but untracked files present (use "git add" to track)

Case 2: rm –cached on existing file.

If ‘rm –cached <existing-file-name>.’command is utilized on the existing file on git then this file will be considered for delete and endures as untracked on the machine. If we make a commit after this command then the file on Github will be deleted forever. We should be very careful while using this command. So, this case is not advised for unstaging a file.

Do Refer: How To Clean Up Git Branches

2. Unstage Files using git reset

The most effortless way to unstage files on Git is by using the “git reset” command and specify the file you want to unstage.

git reset <commit> -- <path>

By default, the commit parameter is optional: if you don’t specify it, it will be referring to HEAD.

What does the git reset command do?

This command will reset the index entries (the ones you added to your staging area) to their state at the specified commit (or HEAD if you didn’t specify any commits).

Also, we use the double dashes as argument disambiguation meaning that the argument that you are specifying may be related to two distinct objects: branches and directories for example.

As a quick example, let’s pretend that you added a file named “README” to your staging area, but now you want to unstage this file.

$ git status

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README

In order to unstage the README file, you would execute the following command

$ git reset -- README

You can now check the status of your working directory again with “git status”

$ git status

On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README

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

As you probably understood by now, the “git reset” command is doing the exact opposite of the “git add” command: it removes files from the index.

Unstage all files on Git

Previously, we have seen how you can unstage a file by specifying a path or a file to be reset.

In some cases, you may want to unstage all your files from your index.

To unstage all files also you can use the “git reset” command without specifying any files or paths.

$ git reset

Again, let’s pretend that you have created two files and one directory and that you added them to your staging area.

$ git status

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README
        new file:   directory/file

In order to unstage all files and directories, execute “git reset” and they will be removed from the staging area back to your working directory.

$ git reset 

$ git status

On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README
        directory/

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

Remove unstaged changes on Git

In some cases, after unstaging files from your staging area, you may want to remove them completely.

In order to remove unstaged changes, use the “git checkout” command and specify the paths to be removed.

$ git checkout -- <path>

Again, let’s say that you have one file that is currently unstaged in your working directory.

$ 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:   README

no changes added to commit (use "git add" and/or "git commit -a")

In order to discard changes done to this unstaged file, execute the “git checkout” command and specify the filename.

$ git checkout -- README

$ git status

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Alternatively, if you want to discard your entire working directory, head back to the root of your project and execute the following command.

$ git checkout -- .

$ git status

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Unstage Committed Files on Git

In some cases, you actually committed files to your git directory (or repository) but you want to unstage them in order to make some modifications to your commit.

Luckily for you, there’s also a command for that.

Unstage Commits Soft

To unstage commits on Git, use the “git reset” command with the “–soft” option and specify the commit hash.

$ git reset --soft <commit>

Alternatively, if you want to unstage your last commit, you can the “HEAD” notation in order to revert it easily.

$ git reset --soft HEAD~1

Using the “–soft” argument, changes are kept in your working directory and index.

As a consequence, your modifications are kept, they are just not in the Git repository anymore.

Inspecting your repository after a soft reset would give you the following output, given that you unstaged the last commit.

$ git status

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   README

What happens if you were to hard reset your commit?

In this case, all changes would be discarded and you would lose your changes.

Unstage Commits Hard

To unstage commits on Git and discard all changes, use the “git reset” command with the “–hard” argument.

$ git reset --hard <commit>

Note: Be careful when using the reset hard command, you will lose all your changes when hard resetting.

Conclusion

In this tutorial, you learned how you can unstage files easily on Git using the “git reset” command.

You learned that you can either specify a path or a single file to unstage files and keep on working on your files until you commit them to your repository.

If you are curious about Git, we have a whole section dedicated to it on the website, make sure to have a look!

Understanding Processes on Linux

Understanding Processes on Linux | Types of Process in Linux | Creating, Listing, Monitoring, Changing Linux Processes

Are you finding an ultimate guide to provide complete knowledge about Understanding Processes on Linux? This could be the right page for all developers & administrators.

Right from what is processes in Linux to how they are managed on Linux are explained here in a detailed way with simple examples for better understanding. If you are working as a system administrator, then I must say that you would have associated with the processes in Linux in many diverse ways.

Actually, Processes are at the center of the Linux OS designed by the Kernel itself, they represent running operations currently happening on your Linux host. You can perform everything with processes like starting them, interrupt them, resume them, or stop them.

In today’s tutorial, we are going to take a deep look at Linux Processes, what they are, what commands are associated with processes, how they are used on our operating system, what signals are, and how we can select more computational resources to our present processes.

What You Will Learn

By reading this tutorial until the end, you will learn about the following concepts

  • What processes are and how they are created on a Linux system?
  • How processes can be identified on a Linux system?
  • What background and foreground processes are?
  • What signals are and how they can be used to interact with processes?
  • How to use the pgrep as well as the pkill command effectively
  • How to adjust process priority using nice and renice
  • How to see process activity in real-time on Linux

That’s quite a long program, so without further ado, let’s start with a brief description of what processes are.

Linux Processes Basics

In short, processes are running programs on your Linux host that perform operations such as writing to a disk, writing to a file, or running a web server for example.

The process has an owner and they are identified by a process ID (also called PID)

Linux Processes Basics process-identity

On the other hand, programs are lines, or code or lines of machine instructions stored on a persistent data storage.

They can just sit on your data storage, or they can be in execution, i.e running as processes.

Linux Processes Basics program-process

In order to perform the operations they are assigned to, processes need resources: CPU timememory (such as RAM or disk space), but also virtual memory such as swap space in case your process gets too greedy.

Obviously, processes can be startedstoppedinterrupted, and even killed.

Before issuing any commands, let’s see how processes are created and managed by the kernel itself.

Process Initialization on Linux

As we already stated, processes are managed by the Kernel on Linux.

However, there is a core concept that you need to understand in order to know how Linux creates processes.

By default, when you boot a Linux system, your Linux kernel is loaded into memory, it is given a virtual filesystem in the RAM (also called initramfs) and the initial commands are executed.

One of those commands starts the very first process on Linux.

Historically, this process was called the init process but it got replaced by the systemd initialization process on many recent Linux distributions.

To prove it, run the following command on your host

$ ps -aux | head -n 2

Process Initialization on Linux systemd

As you can see, the systemd process has a PID of 1.

If you were to print all processes on your system, using a tree display, you would find that all processes are children of the systemd one.

$ pstree

Process Initialization on Linux pstree

It is noteworthy to underline the fact that all those initialization steps (except for the launch of the initial process) are done in a reserved space called the kernel space.

The kernel space is a space reserved to the Kernel in order for it to run essential system tools properly and to make sure that your entire host is running in a consistent way.

On the other hand, user space is reserved for processes launched by the user and managed by the kernel itself.

user-kernel-space

As a consequence, the systemd process is the very first process launched in the userspace.

Creation of a Processes in Linux

A new process is normally created when an existing process makes an exact copy of itself in memory. The child process will have the same environment as its parent, but only the process ID number is different.

In order to create a new process in Linux, we can use two conventional ways. They are as such:

  • With The System() Function – this method is relatively simple, however, it’s inefficient and has significantly certain security risks.
  • With fork() and exec() Function – this technique is a little advanced but offers greater flexibility, speed, together with security.

Process Creation using Fork and Exec

When you are creating and running a program on Linux, it generally involves two main steps: fork and execute.

Fork operation

A fork is a clone operation, it takes the current process, also called the parent process, and it clones it in a new process with a brand new process ID.

When forking, everything is copied from the parent process: the stack, the heap, but also the file descriptors meaning the standard input, the standard output, and the standard error.

It means that if my parent process was writing to the current shell console, the child process will also write to the shell console.

Process Creation using Fork and Exec fork

 

The execution of the cloned process will also start at the same instruction as the parent process.

Execute operation

The execute operation is used on Linux to replace the current process image with the image from another process.

On the previous diagram, we saw that the stack of the parent process contained three instructions left.

As a consequence, the instructions were copied to the new process but they are not relevant to what we want to execute.

The exec operation will replace the process image (i.e the set of instructions that need to be executed) with another one.

Process Creation using Fork and Exec

If you were for example to execute the exec command in your bash terminal, your shell would terminate as soon as the command is completed as your current process image (your bash interpreter) would be replaced with the context of the command you are trying to launch.

$ exec ls -l

If you were to trace the system calls done when creating a process, you would find that the first C command called is the exec one.

strace-linux

Creating processes from a shell environment

When you are launching a shell console, the exact same principles apply when you are launching a command.

A shell console is a process that waits for input from the user.

It also launches a bash interpreter when you hit Enter and it provides an environment for your commands to run.

But the shell follows the steps we described earlier.

When you hit enter, the shell is forked to a child process that will be responsible for running your command. The shell will wait patiently until the execution of the child process finishes.

On the other hand, the child process is linked to the same file descriptors and it may share variables that were declared on a global scope.

The child process executes the “exec” command in order to replace the current process image (which is the shell process image) in the process image of the command you are trying to run.

The child process will eventually finish and it will print its result to the standard output it inherited from the parent process, in this case, the shell console itself.

shell-execution

Now that you have some basics about how processes are created in your Linux environment, let’s see some details about processes and how they can be identified easily.

Identifying & Listing Running Processes on Linux

The easiest way to identify running processes on Linux is to run the ps command.

$ ps

ps-command

By default, the ps command will show you the list of the currently running processes owned by the current user.

In this case, only two processes are running for my user: the bash interpreter and the ps command I have run into it.

The important part here is that processes have owners, most of the time the user who runs them in the first place.

To illustrate this, let’s have a listing of the first ten processes on your Linux operating system, with a different display format.

$ ps -ef | head -n 10

Identifying running processes on Linux

As you can see here, the top ten processes are owned by the user “root“.

This information will be particularly important when it comes to interacting with processes with signals.

To display the processes that are owned and executed by the current connected user, run the following command

$ ps u

Identifying running processes on Linux

There are plenty of different options for the ps command, and they can be seen by running the manual command.

$ man ps

From experience, the two most important commands in order to see running processes are

ps aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

That corresponds to a BSD-style process listing, where the following command

ps -ef

UID  PID  PPID C STIME TTY  TIME CMD

Corresponds to a POSIX-style process listing.

They are both representing current running processes on a system, but the first one has the “u” option for “user oriented” which makes it easier to read process metrics.
ps-aux

Now that you have seen what processes are and how they can be listed, let’s see what background and foreground processes are on your host.

Here is the description of all the fields displayed by ps -f command:

Sr.No. Column & Description
1 UID: User ID that this process belongs to (the person running it)
2 PID: Process ID
3 PPID: Parent process ID (the ID of the process that started it)
4 C: CPU utilization of process
5 STIME: Process start time
6 TTY: Terminal type associated with the process
7 TIME: CPU time taken by the process
8 CMD: The command that started this process

Also, there are other options that can be used along with ps command:

Sr.No. Option & Description
1 -a: Shows information about all users
2 -x: Shows information about processes without terminals
3 -u: Shows additional information like -f option
4 -e: Displays extended information

How to Control Processes in Linux?

In Linux, there are some commands for controlling processes like kill, pkill, pgrep, and killall, here are a few key examples of how to use them:

$ pgrep -u tecmint top
$ kill 2308
$ pgrep -u tecmint top
$ pgrep -u tecmint glances
$ pkill glances
$ pgrep -u tecmint glances

Types of Processes

Basically, there are two types of processes in Linux:

  • Foreground processes (also referred to as interactive processes) – these are initialized and controlled through a terminal session. In other words, there has to be a user connected to the system to start such processes; they haven’t started automatically as part of the system functions/services.
  • Background processes (also referred to as non-interactive/automatic processes) – these are processes not connected to a terminal; they don’t expect any user input.

Background and foreground processes

The definition of background and foreground processes is pretty self-explanatory.

Jobs and processes in the current shell

A background process on Linux is a process that runs in the background, meaning that it is not actively managed by a user through a shell for example.

On the opposite side, a foreground process is a process that can be interacted with via direct user input.

Let’s say for example that you have opened a shell terminal and that you typed the following command in your console.

$ sleep 10000

As you probably noticed, your terminal will hang until the termination of the sleep process. As a consequence, the process is not executed in the background, it is executed in the foreground.

I am able to interact with it. If I press Ctrl + Z, it will directly send a stop signal to the process for example.

Jobs and processes in the current shell foreground

However, there is a way to execute the process in the background.

To execute a process in the background, simply put a “&” sign at the end of your command.

$ sleep 10000 &

As you can see, the control was directly given back to the user and the process started executing in the background

Jobs and processes in the current shell background

To see your process running, in the context of the current shell, you can execute the jobs command

$ jobs

Jobs and processes in the current shell jobs

Jobs are a list of processes that were started in the context of the current shell and that may still be running in the background.

As you can see in the example above, I have two processes currently running in the background.

The different columns from left to right represent the job ID, the process state (that you will discover in the next section), and the command executed.

Using the bg and fg commands

In order to interact with jobs, you have two commands available: bg and fg.

The bg command is used on Linux in order to send a process to the background and the syntax is as follows

$ bg %<job_id>

Similarly, in order to send a process to the foreground, you can use the fg in the same fashion

$ fg %<job_id>

If we go back to the list of jobs of our previous example, if I want to bring job 3 to the foreground, meaning to the current shell window, I would execute the following command

$ fg %3

Using the bg and fg commands

By issuing a Ctrl + Z command, I am able to stop the process. I can link it with a bg command in order to send it to the background.

Using the bg and fg commands bg-1

Now that you have a better idea of what background and foreground processes are, let’s see how it is possible for you to interact with the process using signals.

Interacting with processes using signals

On Linux, signals are a form of interprocess communication (also called IPC) that creates and sends asynchronous notifications to running processes about the occurrence of a specific event.

Signals are often used in order to send a kill or a termination command to a process in order to shut it down (also called kill signal).

In order to send a signal to a process, you have to use the kill command.

$ kill -<signal number> <pid>|<process_name>

For example, in order to force an HTTPD process (PID = 123) to terminate (without a clean shutdown), you would run the following command

$ kill -9 123

Signals categories explained

As explained, there are many signals that one can send in order to notify a specific process.

Here is the list of the most commonly used ones:

  • SIGINT: short for the signal interrupt is a signal used in order to interrupt a running process. It is also the signal that is being sent when a user pressed Ctrl + C on a terminal;
  • SIGHUP: short for signal hangup is the signal sent by your terminal when it is closed. Similarly to a SIGINT, the process terminates;
  • SIGKILL: signal used in order to force a process to stop whether it can be gracefully stopped or not. This signal can not be ignored except for the init process (or the systemd one on recent distributions);
  • SIGQUIT: a specific signal sent when a user wants to quit or to exit the current process. It can be invoked by pressing Ctrl + D and it is often used in terminal shells or in SSH sessions;
  • SIGUSR1, SIGUSR2: those signals are used purely for communication purposes and they can be used in programs in order to implement custom handlers;
  • SIGSTOP: instructs the process to stop its execution without terminating the process. The process is then waiting to be continued or to be killed completely;
  • SIGCONT: if the process is marked as stopped, it instructs the process to start its execution again.

In order to see the full list of all signals available, you can run the following command

$ kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

Signals and Processes States

Now that you know that it is possible to interrupt, kill or stop processes, it is time for you to learn about processes states.

States of a Process in Linux

Processes have many different states, they can be :

  • Running: processes running are the ones using some computational power (such as CPU time) in the current time. A process can also be called “runnable” if all running conditions are met, and it is waiting for some CPU time by the CPU scheduler.
  • Stopped: a signal that is stopped is linked to the SIGSTOP signal or to the Ctrl + Z keyboard shortcut. The process execution is suspended and it is either waiting for a SIGCONT or for a SIGKILL.
  • Sleeping: a sleeping process is a process of waiting for some event or for a resource (like a disk) to be available.

Here is a diagram that represents the different process states linked to the signals you may send to them.

Signals and Processes States process-states

Now that you know a bit more about process states, let’s have a look at the pgrep and pkill commands.

Manipulating Process with pgrep and pkill

On Linux, there is already a lot that you can do by simply using the ps command.

You can narrow down your search to one particular process, and you can use the PID in order to kill it completely.

However, there are two commands that were designed in order for your commands to be even shorter: pgrep and pkill

Using the pgrep command

The pgrep command is a shortcut for using the ps command piped with the grep command.

The pgrep command will search for all the occurrences for a specific process using a name or a defined pattern.

The syntax of the pgrep command is the following one

$ pgrep <options> <pattern>

For example, if you were to search for all processes named “bash” on your host, you would run the following command

$ pgrep bash<

The pgrep command is not restricted to the processes owned by the current user by default.

If another user was to run the bash command, it would appear in the output of the pgrep command.

Using the pgrep command pgrep

It is also possible to search for processes using globbing characters.

Using the pgrep command pgrep-globbing

Using the pkill command

On the other hand, the pkill command is also a shortcut for the ps command used with the kill command.

The pkill command is used in order to send signals to processes based on their IDs or their names.

The syntax of the pkill command is as follows

$ pkill <options> <pattern>

For example, if you want to kill all Firefox windows on your host, you would run the following command

$ pkill firefox

Similar to the pgrep command, you have the option to narrow down your results by specifying a user with the -u option.

To kill all processes starting with “fire” and owned by the current user and root, you would run the following command

$ pkill user,root fire*

If you don’t have the right to stop a process, you will get a permission denied error message to your standard output.

Using the pkill command permission-denied-1

You also have the option to send specific signals by specifying the signal number in the pkill command

For example, in order to stop Firefox with a SIGSTOP signal, you would run the following command

$ pkill -19 firefox<

Changing Linux Process Priority using nice and renice

On Linux, not all processes are given the same priority when it comes to CPU time.

Some processes, such as very important processes run by root, are given a higher priority in order for the operating system to work on tasks that truly matter to the system.

Process priority on Linux is called the nice level.

The nice level is a priority scale going from -20 to 19.

The lower you go on the niceness scale, the higher the priority will be.

Similarly, the higher you are on the niceness scale, the lower your priority will be.

In order to remember it, you can remember the fact that “the nicer you are, the more you are willing to share resources with others”.

djusting process priority using nice and renice

In order to start a certain program or process with a given nice level, you will run the following command

$ nice -n <level> <command>

For example, in order to run the tar command with a custom tar level, you would run the following command

$ nice -n 19 tar -cvf test.tar file

Similarly, you can use the renice command in order to set the nice level of a running process to a given value.

$ renice -n <priority> <pid>

For example, if I have a running process with the PID 123, I can use the renice command in order to set its priority to a given value.

$ renice -n 18 123

Niceness and permissions

If you are not a member of the sudo group (or a member of the wheel group on Red Hat-based distributions), there are some restrictions when it comes to what you can do with the nice command.

To illustrate it, try to run the following command as a non-sudo user

$ nice -n -1 tar -cvf test.tar file

nice: cannot set niceness: Permission denied

nice-permissions

When it comes to niceness, there is one rule that you need to know:

As a non-root (or sudo) user, you won’t be able to set a nice level lower than the default assigned one (which is zero), and you won’t be able to renice a running process to a lower level than the current one.

To illustrate the last point, launch a sleep command in the background with a nice value of 2.

$ nice -n 2 sleep 10000 &

Next, identify the process ID of the process you just created.

Niceness and permissions

Now, try to set the nice level of your process to a value lower to the one you specified in the first place.

$ renice -n 1 8363

renice
As you probably noticed, you won’t be able to set the niceness level to 1, but only to a value higher than the one you specified.

Now if you choose to execute the command as sudo, you will be able to set the nice level to a lower value.

sudo-rence

Now that you have a clear idea of the nice and renice commands, let’s see how you can monitor your processes in real-time on Linux.

Monitoring processes on Linux using top and htop

In a previous article, we discussed how it is possible to build a complete monitoring pipeline in order to monitor Linux processes in real-time.

Using top on Linux

The top is an interactive command that any user can run in order to have a complete and ordered listing of all processes running on a Linux host.

To run top, simply execute it without any arguments.

The top will run in interactive mode.

$ top

If you want to run top for a custom number of iterations, run the following command

$ top -n <number><

top

The top command will first show recap statistics about your system at the top, for example, the number of tasks running, the percentage of CPU used, or the memory consumption.

Right below it, you have access to a live list of all processes running or sleeping on your host.

This view will refresh every three seconds, but you can obviously tweak this parameter.

To increase the refresh rate in the top command, press the “d” command and choose a new refresh rate

refresh-rate

Similarly, you can change the nice value of a running process live by pressing the “r” key on your keyboard.

The same permissions rules apply if you want to modify processes to a value lower to the one they are already assigned.

As a consequence, you may need to run the command as sudo.

renice-top

Using htop on Linux

Alternatively, if you are looking for a nicer way to visualize processes on your Linux host, you can use the htop command.

By default, the htop command is not available on most distributions, so you will need to install it with the following instructions.

$ sudo apt-get update
$ sudo apt-get install htop

If you are running a Red Hat based distribution, run the following commands.

$ sudo yum -y install epel-release
$ sudo yum -y update
$ sudo yum -y install htop

Finally, to run the htop command, simply run it without any arguments.

$ htop

htop

As you can see, the output is very similar except that it showcases information in a more human-friendly output.

Conclusion

In this tutorial, you learned many concepts about processes: how they are created, how they can be managed, and how they can be monitored effectively.

If you are looking for more tutorials related to Linux system administration, we have a complete section dedicated to it on the website, so make sure to check it out.

Until then, have fun, as always.