Sign In
Sign In

Git Checkout: How to Work with Branches

Git Checkout: How to Work with Branches
Hostman Team
Technical writer
Git
26.09.2024
Reading time: 11 min

The checkout command in the Git version control system is responsible for switching between different branches in a repository. Each switch updates the files in the working directory based on the data stored in the selected branch. Every subsequent commit is automatically added to the active branch chosen earlier using the checkout command.

This guide will cover various ways to use the git checkout command and other related commands (such as git branch, git reflog, and git remote show), which enable interaction with both local and remote branches.

Creating a Repository

First, let's prepare a directory for a test Git project:

mkdir project

Then, navigate to it:

cd project

Finally, initialize the Git repository:

git init

Creating a File and Committing

To understand how branch switching affects the working directory (and the repository as a whole), we’ll create a basic project source file with trivial content inside:

sudo nano file_m

The content of the file will be:

file in master

Let’s check the status of the working directory:

ls

There is only one file:

file_m

Now let’s stage the changes:

git add file_m

Then, commit them:

git commit -m "First commit"

Throughout this guide, we’ll observe how working with branches impacts the contents of the working directory — particularly the files we create or edit.

Creating a New Branch

Let’s assume we want to introduce a new feature into our project but are unsure of its necessity or effectiveness. Essentially, we want to test a hypothesis with the ability to revert changes to the stable version of the project.

To do this, Git allows us to create separate branches and switch between them. This way, we can test the project both with and without the feature. But first, let’s check which branch we are currently on:

git branch

The console will display the output with the active branch, master, highlighted:

* master

We committed the previous changes to this branch, which means the file_m file is in this branch. Now, we’ll create a separate branch for our new feature using the same git branch command but with a new branch name:

git branch feature1

It’s important to note that git branch does not automatically switch to the newly created branch. We can confirm this by rechecking the list of existing branches:

git branch

You’ll notice that the list now includes the feature1 branch, but the active branch (marked by green and asterisk) is still master:

 feature1
* master

Now we have multiple branches to switch between.

Switching to an Existing Branch

To manually switch to an existing branch, use the checkout command, specifying the branch name:

git checkout feature1

The console will display a message confirming the successful switch:

Switched to branch 'feature1'

Let’s check the list of existing branches again:

git branch

As you can see, the active branch is now feature1:

* feature1
 master

Let’s check the working directory again:

ls

It still contains the same file that was “inherited” from the master branch:

file_m

Since the feature1 branch is for modifying the project, we’ll create another file:

sudo nano file_f1

Its content will be:

file in feature1

Let’s stage the changes:

git add file_f1

And commit them:

git commit -m "Commit from feature1"

Now, check the working directory again:

ls

You’ll see there are now multiple files:

file_m  file_f1

Now, let’s switch back to the main branch:

git checkout master

After this, the working directory will only contain the original file:

file_m

Each time we switch between branches, the files in the working directory update to reflect the state of the commits that exist in the active branch.

Switching to a New Branch

Let’s assume we want to add another feature to our project, meaning we’ll need to create a new branch. First, ensure that we’re on the master branch:

git checkout master

Now, attempt to switch to a branch that hasn’t been created yet, feature2:

git checkout feature2

As expected, you’ll receive an error:

error: pathspec 'feature2' did not match any file(s) known to git

However, the git checkout command allows you to create new branches while switching to them by using the -b flag:

git checkout -b feature2

The console will display a message confirming the successful switch:

Switched to a new branch 'feature2'

In essence, git checkout with the -b flag is equivalent to running the following two commands:

git branch feature2
git checkout feature2

Recheck the list of existing branches:

git branch

Now we have the feature2 branch, which became active immediately upon its creation:

 feature1
* feature2
 master

The new branch is based on the branch (its working directory and commit history) that was active before it was created. Since we switched to the master branch before creating feature2, the working directory should only contain the file file_m but not file_f1.

Deleting a Branch

You cannot delete a branch that is currently active:

git branch -d feature2

The -d flag indicates the request to delete the specified branch. The console will display an error message:

error: Cannot delete branch 'feature2' checked out at '/root/project'

So, first, switch to another branch:

git checkout master

Then proceed with the branch deletion:

git branch -d feature2

This time, the console will display a message confirming the successful deletion of the branch:

Deleted branch feature2 (was 24c65ff).

The list of existing branches will now look like this:

 feature1
* master

Creating a Branch from Another Branch

Git allows you to specify which branch to base a new branch on without switching branches first.

Let’s first ensure we're currently on the master branch:

git checkout master

At this point, the special HEAD pointer points to the active master branch, which, in turn, points to the latest commit of this branch.

Previously, we created the feature2 branch from the active master branch. However, now we’ll create the feature2 branch from the feature1 branch (instead of master) without explicitly switching to it — we'll stay on master:

git checkout -b feature2 feature1

Now the active branch is feature2. Let’s check the contents of the working directory:

ls

As you can see, the state of the directory matches feature1, not master:

file_m  file_f1

We can also look at the commit history:

git log

The feature2 branch contains both the commits from master and from feature1:

commit fb1b1616c85c258f647df4137df535df5ac17d6c (HEAD -> feature2, feature1)
Author: root <root@166.1.227.189.net>
Date:   Tue Feb 13 02:18:02 2024 +0100

   Commit from feature1

commit 24c65ffab574a5e478061034137298ca2ce33c94 (master)
Author: root <root@166.1.227.189.net>
Date:   Mon Feb 12 11:30:56 2024 +0100

   First commit

Resetting a Branch to Another Branch

In addition to creating a branch from another, the checkout command can reset an existing branch to match the state of another branch.

For example, we can reset the feature2 branch to match the state of master:

git checkout -B feature2 master

Note the use of the -B flag instead of -b.

The console will show the following message:

Reset branch 'feature2'

Check the working directory:

ls

Only one file remains:

file_m

The list of "inherited" commits in the feature2 branch will now match the commits of the master branch:

git log

In the console, there will only be one commit — the very first one:

commit 24c65ffab574a5e478061034137298ca2ce33c94 (HEAD -> feature2, master)
Author: root <root@166.1.227.189.net>
Date:   Mon Feb 12 11:30:56 2024 +0100

   First commit

Viewing Checkout History

Switching branches is not just a read operation; it makes changes to the repository, creating a new record in the checkout history.

Git has a special command to display the full history of branch switches:

git reflog

The history of operations is displayed from bottom to top, with the most recent switches at the top:

fb1b161 (HEAD -> feature2, feature1) HEAD@{1}: checkout: moving from master to feature2
24c65ff (master) HEAD@{2}: checkout: moving from feature1 to master
fb1b161 (HEAD -> feature2, feature1) HEAD@{3}: commit: Added the first feature
24c65ff (master) HEAD@{4}: checkout: moving from master to feature1
24c65ff (master) HEAD@{5}: checkout: moving from feature2 to master
24c65ff (master) HEAD@{6}: checkout: moving from feature1 to feature2
24c65ff (master) HEAD@{7}: checkout: moving from master to feature1
24c65ff (master) HEAD@{8}: commit (initial): First commit

Switching to a Remote Branch

Adding a Remote Repository

Suppose we have a remote GitHub repository we are working with over HTTPS:

git remote add repository_remote https://github.com/USER/REPOSITORY.git

Alternatively, we could access it via SSH:

git remote add repository_remote git@github.com:USER/REPOSITORY.git

In this case, an SSH key needs to be generated beforehand:

ssh-keygen -t rsa -b 4096 -C "GITHUB_ACCOUNT_EMAIL"

The public key (.pub), located in the /.ssh/known_hosts/ directory, is copied into the GitHub account settings under SSH Keys.

In our case, the remote repository will be Nginx:

git remote add repository_remote https://github.com/nginx/nginx

Fetching Files from a Remote Branch

After adding the remote repository, we can check the list of all its branches:

git remote show repository_remote

Before switching to a remote branch, we first need to retrieve detailed information about the remote repository — branches and tags:

git fetch repository_remote

You can also fetch from all remote repositories at once:

git fetch --all

Now, we can switch directly to a remote branch and retrieve its files into the working directory:

git checkout branches/stable-0.5

In older Git versions, it was necessary to specify the remote repository explicitly:

git checkout repository_remote/branches/stable-0.5

Now, if you run the command:

git branch

You will see the remote branch listed as active:

* branches/stable-0.5
 feature2
 feature1
 master

Check the state of the working directory:

ls

Now it contains the following directories:

auto  conf  contrib  docs  misc  src

You can delete a remote branch just like a local one. First, switch to a different branch:

git checkout master

Then, delete the remote branch:

git branch -D branches/stable-0.5

Now the branch list looks like this:

 feature2
 feature1
* master

Switching to a Specific Commit

Just like switching branches, you can switch to a specific commit. However, it's important to understand the difference between commits and branches.

Branches diverge from the project's timeline without disrupting the sequence of changes, while commits are more like progress points, containing specific states of the project at particular times.

Let’s first switch to the latest branch, which contains the most commits:

git checkout feature2

To switch to a specific commit, provide the commit hash (ID) instead of the branch name:

git checkout fb1b1616c85c258f647df4137df535df5ac17d6c

To find the hash, use the command:

git log

In our case, the commit history looks like this (only the hashes may differ):

commit fb1b1616c85c258f647df4137df535df5ac17d6c (HEAD -> feature2, feature1)
Author: root <root@166.1.227.189>
Date:   Tue Feb 13 02:18:02 2024 +0100

   Commit from feature1

commit 24c65ffab574a5e478061034137298ca2ce33c94 (master)
Author: root <root@166.1.227.189>
Date:   Mon Feb 12 11:30:56 2024 +0100

   First commit

After switching to a commit, you can check which branch is currently active:

git branch

The list of branches will now look like this:

* (HEAD detached at fb1b1616c)
 feature2
 feature1
 master

This results in a "detached HEAD" state. Any subsequent commits won’t belong to any existing branch.

However, this mode is risky — the lack of a specific branch in the HEAD pointer may result in data loss. For this reason, it's common to "wrap" the chosen commit in a new branch to continue project modifications.

Switching to a specific commit is usually used to review changes made at a particular stage of development.

Difference Between checkout and switch

In later Git versions (2.23 and above), there’s another command for working with branches — switch.

These commands are quite similar, but switch is more specialized:

  • git switch is a new command focused more on branch operations. At the same time, git checkout is an older command that can also handle "peripheral" tasks, such as creating new branches while switching or modifying the working directory to match a specific commit's state.

  • git checkout has a more universal (and less standardized) syntax, which can make it seem more complex and prone to errors compared to git switch.

Conclusion

In this guide, we’ve covered the git checkout command, primarily used for switching between different branches in a repository.

Here’s a complete list of what the checkout command can do:

  • Switch between existing local branches.

  • Create new local branches,

  • Create new local branches based on other branches.

  • Reset existing local branches to the state of other branches.

  • Switch between existing remote branches (and download their files into the working directory).

  • Switch to a specific commit from a local or remote branch.

After switching to another branch, the use of commands like git add and git commit typically follows to index changes and update the repository state within that branch.

Always be cautious — switching branches after making changes in the working directory without committing can result in data loss.

For more information on working with Git, refer to the official documentation.

Git
26.09.2024
Reading time: 11 min

Similar

Git

Working with Git Tags

Git has been around for almost 20 years, yet it remains the most popular distributed version control system. It is best known for GitHub, the largest remote Git repository where developers store their code, document changes, and save previous versions. To help manage versions efficiently, Git provides special markers called tags. This article will explore what Git tags are and how to use them. What Are Git Tags? To understand Git tags, let's first clarify some related concepts. Commit: A commit is a saved version of a project. Branch: A collection of commits that visually represents the history of changes in a project. Multiple branches can exist simultaneously. Now, let’s define tags. Git tags are markers used to highlight important commits. They help track version history, as responsible developers often tag each new version. Like branches, Git tags point to a specific commit, but unlike branches, they do not have a history of commits. Now, let's see how to work with Git tags—create, view, publish, replace, switch, and delete them. How to Create Git Tags Git has two main types of tags: annotated and lightweight. Each is created differently. Creating Annotated Tags Annotated tags store complete version information, including developer names, emails, and timestamps. They are created using special Git flags, -a and -m, as shown in the example below: git tag -a ver-2.5 -m "beta version 2.5" git tag Output: ver-0.1 ver-1.6 ver-2.5 git tag is the main command for working with tags. -a creates an annotated tag with a specified identifier. -m adds a message. If omitted, a text editor will open for message input. To view details of an annotated tag along with its commit, use: git show ver-2.5 Output: tag ver-2.5 Tagger: Marianne Smith <m.smith@company.com> Date: Fri Mar 28 11:02:35 2025 beta version 2.5 commit bf93b7eaa928fd77a55453118313701b04874051 Author: James Brown <j.brown@company.com> Date: Mon Jan 6 09:41:02 2025 This displays the tagger's information, the commit hash, the author, and the creation date. To verify that the tag was created successfully, use: git tag -n Creating Lightweight Tags Lightweight tags are simple pointers to commits, typically used for temporary markers. They store only the commit’s hash. Here’s how to create one: git tag ver-2.5a git tag Output: ver-0.1 ver-1.6 ver-2.5 ver-2.5a ver-2.6 To view a lightweight tag's commit information: git show ver-2.5a Output: commit bf93b7eaa928fd77a55453118313701b04874051 Author: James Brown <j.brown@company.com> Date: Mon Jan 6 09:41:02 2022 -0300 Unlike annotated tags, lightweight tags do not store additional metadata. Adding and Deleting Git Tags in Remote Repositories To push a tag to a remote repository: git push origin ver-2.5 Here, origin refers to the default remote repository. To push all tags at once: git push origin --tags To delete a tag from a remote repository: git push origin --delete ver-2.5 To delete a tag locally (not on the remote repository): git tag -d ver-2.5 Switching Between Tags To switch to a specific tag: git checkout ver-2.5 However, this detaches the HEAD pointer, meaning any subsequent changes will not be associated with any existing branch. If you make changes, create a new branch to keep them: git checkout -b new-branch Viewing a List of Git Tags To list all available tags: git tag Output: ver-0.1 ver-1.6 ver-2.5 ver-2.5a ver-2.6 To filter tags using a pattern: git tag -l *xyz* If you have tags like ver-1.6xyz, ver-2.5xyz, and ver-2.6xyz, this command will output: ver-1.6xyz ver-2.5xyz ver-2.6xyz Reassigning or Replacing Tags To update an existing tag, use the -f flag for forced replacement: git tag -a -f ver-2.5a bf93b7eaa928fd77a55453118313701b04874051 This reassigns the tag to a specific commit hash. However, this will delete the old tag information, so use it carefully. Summary Git tags make version control more flexible and manageable. The commands covered here are simple yet powerful, making them easy to learn even for beginners. 
03 April 2025 · 4 min to read
Git

How to Use GitHub Copilot with Python

GitHub Copilot is a tool that helps developers write code faster and more efficiently by providing suggestions and even entire blocks of code based on comments, variable names, function names, and more. GitHub Copilot saves time when writing standard code structures and algorithms. It is helpful for beginners just learning to develop in a new language and for experienced developers who want to avoid manually writing repetitive functions and structures. GitHub Copilot can be integrated into various development environments, including: Visual Studio Neovim VS Code JetBrains IDEs It also supports a wide range of programming languages, such as: Python JavaScript Go Java C# TypeScript C++ Ruby Rust Shell script Kotlin Swift GitHub Copilot is compatible with popular frameworks and libraries like React, AngularJS, VueJS, Spring, Django, Ruby on Rails, and more. In this tutorial, we’ll explain how to use GitHub Copilot when developing in Python and how it can help improve coding efficiency. Key Features of GitHub Copilot Autocomplete – Provides real-time code suggestions and autocompletion. Code Prediction – Predicts the next steps in your code and offers options to complete structures. Code Search – Helps find relevant code within a project using keywords or code snippets. Code Refactoring – Assists in optimizing and modifying existing code with refactoring features. GitHub Copilot is currently available as a subscription service for $10 monthly. How GitHub Copilot Works GitHub Copilot provides suggestions and autocomplete features based on user comments written in natural language and existing code. To achieve this, GitHub trained Copilot using publicly available repositories hosted on its platform. The effectiveness of Copilot depends on the availability of public repositories in a given programming language. It works well with popular languages like Python and offers reliable suggestions. However, for less common languages, its performance may be weaker, providing fewer and less accurate recommendations. Integrating GitHub Copilot with PyCharm PyCharm, a JetBrains IDE, supports GitHub Copilot. To integrate it into your project, follow these steps: Visit github.com/features/copilot and click Get started for free. Log in to GitHub or create an account.  Now, you can install the GitHub Copilot plugin in PyCharm: Open PyCharm. Go to File > Settings. Navigate to Plugins and search for GitHub Copilot. Click Install to add the plugin. After installation, open the Tools menu, find GitHub Copilot and click Login to GitHub. A window will appear with an authorization link and a special code. Follow the link, enter the code, and confirm authorization. Now, GitHub Copilot is fully integrated into your PyCharm project. How to Use GitHub Copilot Let's write a simple function to verify that we have successfully installed the GitHub Copilot plugin. For example, start typing a function to add two numbers, like: def add(a, b): As you begin typing, Copilot will suggest completing the function: Suggested code appears in gray and italicized text. To accept a suggestion, press Tab. To reject a suggestion, press Esc. Useful GitHub Copilot Shortcuts Action Windows Mac Activate inline suggestions Alt+\ Option+\ View next suggestion Alt+] Option+] View previous suggestion Alt+[ Option+[ Accept suggestion Tab Tab Reject suggestion Esc Esc Open all suggestions in a new window Ctrl+Enter Ctrl+Enter Using Copilot with Comments GitHub Copilot doesn’t just rely on function names—it also generates code based on comments. For example, if you write a function for matrix multiplication with a descriptive comment: def multiply_matrices(A, B): # Multiply matrix A and B and return the result Copilot may suggest the following: def multiply_matrices(A, B): # Multiply matrix A and B and return the result rows1 = len(A) cols1 = len(A[0]) rows2 = len(B) cols2 = len(B[0]) if cols1 != rows2: raise ValueError("The number of columns in the first matrix must be equal to the number of rows in the second matrix") result = [[0 for j in range(cols2)] for i in range(rows1)] for i in range(rows1): for j in range(cols2): for k in range(cols1): result[i][j] += A[i][k] * B[k][j] return result To verify that this function works correctly, let’s use the NumPy library: import numpy as np matrix1 = [[15,24],[12,44]] matrix2 = [[112, 22],[55,90]] m1 = np.array([[15,24],[12,44]]) m2 = np.array([[112, 22],[55,90]]) print(multiply_matrices(matrix1, matrix2),'\n') print(np.dot(m1, m2)) Output: [[3000, 2490], [3764, 4224]] [[3000 2490] [3764 4224]] As you can see, the function Copilot correctly performs matrix multiplication. Cons of Using GitHub Copilot GitHub Copilot is a very useful tool, but it has some drawbacks. Copilot Doesn't Test Its Code The code suggested by Copilot may contain errors. It does not perform self-checks, meaning developers must test the generated code themselves. Additionally, Copilot doesn’t always produce optimized code, both in terms of efficiency and structure. In summary, all Copilot-generated code must be reviewed and tested. Conflicts with IDEs Modern Integrated Development Environments (IDEs) do more than just provide a space for writing and debugging code—they also offer built-in suggestions. For example, when using a built-in function in PyCharm, the IDE provides information about its attributes. At the same time, Copilot might suggest something different, which can be confusing for the developer. Potential Copyright Issues This is a controversial aspect of using Copilot in commercial development. Since Copilot was trained on public repositories, it could theoretically suggest licensed code. This raises concerns about intellectual property rights when using Copilot-generated code in proprietary projects. Negative Impact on Developer Skills Copilot doesn’t teach developers how to write code—it writes it for them. For junior developers, it’s important to gain hands-on experience by implementing common functions and algorithms manually. Over-reliance on Copilot might slow down skill development. Conclusion GitHub Copilot is a useful tool for handling repetitive coding tasks. According to GitHub’s own research: 74% of developers reported focusing on more enjoyable aspects of their work, 88% felt more productive, 96% completed repetitive tasks faster. Copilot should be seen as an assistant—someone you can delegate tasks to while focusing on more important and complex problems. However, developers must carefully review all code generated by Copilot to ensure quality and correctness. 
24 March 2025 · 6 min to read
Git

Best Practices for Using the git stash Command

Git is a distributed version control system developed by Linus Torvalds. It has become the standard in software development due to its efficiency and flexibility. During the development process, there are situations when you need to urgently switch to another branch using the checkout command and make changes related to a different task. However, the current changes may not be ready for a commit yet, and you don’t want to lose them. In such situations, the git stash command comes to the rescue. This tool is indispensable, allowing you to safely store current changes for a while and then return to them without disrupting the integrity of the repository. Let’s explore how to use git stash in development. Basics of git stash Let's think about how we normally work with the codebase and Git. We create something (a function or a small module), then run git add, followed by git commit and git push. Great; we have finished the task and can move on to the next one. But what if the context changes, and you need to switch urgently? You may not have finished writing the module yet, but you must complete another task now. You don’t want to leave the commit unfinished. This is where git stash comes in. So, what does it do? The process of saving temporary changes consists of two stages: stash: We save the changes to a special storage. You can also add a comment for them. pop or apply: We bring the changes back into our working directory. Preparation The version control system must track changes you are going to stash. You can add files to the tracked list using the command: git add . Creating a Stash To create a stash, use the following command: git stash Output: Saved working directory and index state WIP on master: 099797d start By default, the stash name contains the abbreviation “WIP” (Work In Progress) and the branch name. If you want to specify a comment, you can use the following commands: git stash push or git stash save: git stash push -m "<your comment>" The result will be: Saved working directory and index state On master: <your comment> The same result will occur with this command: git stash save "<your comment>" However, this command is considered deprecated — you can check the documentation for more details. Retrieving Changes Now, let’s return to the original task. We need to bring back the hidden changes. Use the command: git stash pop The output will tell you that the changes have been applied to the current working area and can now be used. It will also indicate that all data has been removed from the special temporary storage. If you need to apply the changes without removing them from the stash, use the command: git stash apply Additional Commands and Parameters List All Stashes To view the list of changes that have been stashed in the repository, you can use the command: git stash list Example output: stash@{0}: On master: User Story #2010stash@{1}: WIP on master: 099797d start Applying Specific Changes by Index To apply a specific change, you can use the pop command with the stash index: git stash pop 'stash@{1}' Example output: no changes added to commit (use "git add" and/or "git commit -a")Dropped stash@{1} (563f9c20ab12525795911fbed0c4ebf4a1298b4e) Additional Parameters for the git stash Command If you need to stash changes while keeping them in the working directory, use the --keep-index flag. In this case, files added to the tracked list using the git add command will remain: git stash --keep-index Output: Saved working directory and index state WIP on master: 099797d start If you call git status after this, the modified files will still be there: On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: GitStash/Program.cs modified: GitStash/SomeModule.cs If you need to add files that git does not track yet, use the --include-untracked flag: git stash --include-untracked When you retrieve changes using pop, you will see a message about the presence of untracked files: ... Untracked files: (use "git add <file>..." to include in what will be committed) GitStash/NewClass.cs ... Sometimes it may be convenient to split the uncommitted changes into separate stashes. In this case, the git stash -p command will help: git stash -p For each change, hiding will be done separately, with a prompt for confirmation. Here are the options for confirmation: ? — to show all options y — to stash the change n — to not stash this part of the change q — to stash all selected parts and finish Viewing Specific Changes in a Stash The show command displays information about the changes in a specific stash, for example: git stash show GitStash/Program.cs    | 3 ++- GitStash/SomeModule.cs | 7 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) You can also specify the index of a specific stash: git stash show 'stash@{1}' Example output: GitStash/SomeModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) Clearing Changes from a Stash To remove a specific stash, you can use the drop command. If you don't specify an index, it will remove the most recent set of stashed changes: git stash drop Or: git stash drop 'stash@{1}' Output: Dropped stash@{1} (bedb3c2add59a3f203e2367602328dca8b33b6e9) To completely clear the stash storage, you can use the command: git stash clear Creating a New Branch from a Stash To create a new branch based on stashed changes, use the following command: git stash branch <branch name> <stash index> Or simply: git stash branch <branch name> For example: git stash branch some-feature stash@{2} How It Works The set of changes we hide in the stash is actually a series of commits. Running this command creates two or three commits: The commit stash@{0} contains the stashed files. The parent commit is the HEAD commit in Git's current working directory. If we run the command with the --keep-untracked flag, a separate commit will be created for the untracked files. What happens when you run the pop command? The stashed changes are returned to the repository's working copy and indexed by Git. Other stashes are shifted. The extracted commits are deleted. The .git/refs/stash file contains a reference to the last commit for the stash. cat .\.git\refs\stash Output: 07ea0c456356e883610f43c20d9cb298ff2ebb8a Use Cases Let's look at some common use cases for this mechanism in practice: Backup Before Merge or Rebase The merge / rebase commands are necessary when working with multiple branches. However, conflicts often arise that can cause important changes in the current working directory to be lost. Before performing a merge, ensure that the current branch is up to date, i.e., it doesn't contain unsaved changes. If you have unsaved changes that should be preserved before merging, run this command: git stash push -m "Backup before branch merge" Proceed with the merge, running merge or rebase. Conflicts may arise between the changes in the current branch and the changes in the other branch when executing these commands. You can resolve conflicts using either IDE tools or Git. After successfully completing the merge or rebase, you can restore the changes to the current working directory using apply or pop. Non-Debugging Changes The stash mechanism can also be helpful for working with non-debugging changes, such as temporary fixes, comments, or code formatting. Instead of committing these changes to the current commit, you can use git stash to save them temporarily. This helps in creating clean commits and improves the structure of the Git history. Effective Project Configuration Management Another scenario for using git stash is effectively managing project configurations. Depending on the task or environment you are working in, you might need to modify configuration files, but permanently saving them might not be practical. Saving different configurations Suppose there is a configuration file that defines the parameters for your application (e.g., config.json). You need several versions of this file for different use cases (e.g., local development, testing, and production). You can use the stash to save these configurations. # Saving the configuration for local development git stash save "Local configuration" # Saving the configuration for testing git stash save "Testing configuration" # Saving the configuration for the production environment git stash save "Production configuration" Applying configurations as needed When you need to switch between different configurations, simply use git stash apply or git stash pop to apply the corresponding stash: # Applying the configuration for testinggit stash apply stash@{1} Tips for Effective Using git stash Use clear stash descriptions. The default messages created for stashes usually don’t convey the essence of the changes — they’re simply an abbreviation like WIP, a commit ID, and the branch name: WIP on master: 099797d start Use the push or save commands to add descriptive messages, for example: git stash save "test configuration" Or: git stash push -m "Started working on issue #11 - added contract for the module" Check and clean your stashes. During long-term project development, you may accumulate a large number of changes that are no longer relevant. Use the list and show commands to view the changes and git stash drop to remove obsolete stashes. This mechanism is not intended for long-term data or change storage. Use stash with other commands. You can combine git stash with other commands, such as git stash branch, to create new branches, or with the rebase and merge commands to back up local changes. Conclusion In this article, we’ve explored the git stash command and its use cases. git stash is a powerful tool that can significantly simplify managing changes in your repository and improve your workflow. We’ve examined both basic and advanced scenarios for using this tool, including creating, applying, extracting, and managing stash entries.
07 March 2025 · 8 min to read

Do you have questions,
comments, or concerns?

Our professionals are available to assist you at any moment,
whether you need help or are just unsure of where to start.
Email us
Hostman's Support