08. Undoing Changes

The parameters that you pass to git reset and git checkout determine their scope. When you don’t include a file path as a parameter, they operate on whole commits. That’s what we’ll be exploring in this section. Note that git revert has no file-level counterpart.

git checkout

In Git terms, a "checkout" is the act of switching between different versions of a target entity. The git checkout command operates upon three distinct entities: files, commits, and branches.

Checking out a commit makes the entire working directory match that commit. This can be used to view an old state of your project without altering your current state in any way. Checking out a file lets you see an old version of that particular file, leaving the rest of your working directory untouched.

The git checkout command serves three distinct functions:

  • Checking out branches: git checkout master - check out specific branch.

  • Checking out commits: git checkout <commit> - update all files in the working directory to match the specified commit. You can use either a commit hash or a tag as the <commit> argument. This will put you in a detached HEAD state.

  • Checking out files: git checkout <commit> <file> check out a previous version of a file. This turns the <file> that resides in the working directory into an exact copy of the one from <commit> and adds it to the staging area.

git checkout <branch> # switch HEAD branch
git checkout -b <branch> # create and switch new branch
git checkout <branch> -- <filename> # checkout single file from different branch
git checkout <commit-hash> -b <new_branch_name> # checkout and create a new branch from existing commit

git reset

On the commit-level, resetting is a way to move the tip of a branch to a different commit. This can be used to remove commits from the current branch.

In addition to moving the current branch, you can also get git reset to alter the staged snapshot and/or the working directory by passing it one of the following flags:

  • --soft – The staged snapshot and working directory are not altered in any way.

  • --mixed – The staged snapshot is updated to match the specified commit, but the working directory is not affected. This is the default option.

  • --hard – The staged snapshot and the working directory are both updated to match the specified commit.

git checkout hotfix
git reset HEAD~2 # moves the hotfix branch backwards by two commits.

git reset --soft HEAD^1 # move tip of branch one commit before and move all changes to staging area

git reset --mixed HEAD # unstaging all changes, but leaves them in the working directory
git reset --hard HEAD # completely throw away all your uncommitted changes,

git reset <file> # переводит файл из сцены в working directory.
git reset # сбрасывает все файлы со сцены

git reset --hard HEAD~1 # undo last commit

Если имя коммита не будет указано, по умолчанию оно будет HEAD. В этом случае указатель ветки не будет перемещён, но сцена (а также и рабочая директория, если был использован ключ --hard) будет приведена к состоянию последнего коммита.

Если в команде указано имя файла, то команда работает так же, как checkout с именем файла, за исключением того, что только сцена (но не рабочая директория) будет изменена. Если вы подставите имя коммита на место двойной черты, вы сможете получить состояние файла из этого коммита, тогда как в случае с двойной чертой вы получите состояние файла из коммита, на который указывает HEAD.

Whereas reverting is designed to safely undo a public commit, git reset is designed to undo local changes. Because of their distinct goals, the two commands are implemented differently: resetting completely removes a changeset, whereas reverting maintains the original changeset and uses a new commit to apply the undo.

git revert

The git revert <commit> command undoes a specific <commit>. But, instead of removing the commit from the project history, it figures out how to undo the changes introduced by the commit and appends a new commit with the resulting content.

Reverting should be used when you want to remove an entire commit from your project history. It's important to understand that git revert undoes a single commit—it does not "revert" back to the previous state of a project by removing all subsequent commits. In Git, this is actually called a reset, not a revert.

git clean

The git clean command removes untracked files from your working directory.

  • git clean -n - perform a “dry run” of git clean. This will show you which files are going to be removed without actually doing it.

  • git clean -f - remove untracked files from the current directory. The -f (force) flag is required unless the clean.requireForce configuration option is set to false (it's true by default). This will not remove untracked folders or files specified by .gitignore.

  • git clean -f <path> - remove untracked files, but limit the operation to the specified path.

  • git clean -df - remove untracked files and untracked directories from the current directory.

  • git clean -xf - remove untracked files from the current directory as well as any files that Git usually ignores.

Last updated