Showing posts with label GIT Reset. Show all posts
Showing posts with label GIT Reset. Show all posts

Friday, 28 December 2018

GIT: How can I restore a previous version of my project?

Using a version control system like Git brings a fantastic benefit: you can return to any old version of your project at any time.

Returning to an Old Revision

The fastest way to restore an old version is to use the "reset" command:
$ git reset --hard 0ad5a7a6
This will rewind your HEAD branch to the specified version. All commits that came after this version are effectively undone; your project is exactly as it was at that point in time.
The reset command comes with a couple of options, one of the more interesting ones being the "--soft" flag. If you use it instead of --hard, Git will keep all the changes in those "undone" commits as local modifications:
$ git reset --soft 0ad5a7a6
You'll be left with a couple of changes in your working copy and can then decide what to do with them.

Restoring a Revision in a New Local Branch

As said, using the reset command on your HEAD branch is a quite drastic action: it will remove any commits (on this branch) that came after the specified revision. If you're sure that this is what you want, everything is fine.
However, there is also a "safer" way in case you'd prefer leaving your current HEAD branch untouched. Since "branches" are so cheap and easy in Git, we can easily create a new branch which starts at that old revision:
$ git checkout -b old-project-state 0ad5a7a6
Normally, the checkout command is used to just switch branches. However, providing the -b parameter, you can also let it create a new branch (named "old-project-state" in this example). If you don't want it to start at the current HEAD revision, you also need to provide a commit hash - the old project revision we want to restore.
VoilĂ : you now have a new branch named "old-project-state" reflecting the old version of your project - without touching or even removing any other commits or branches.

TIP

Restoring an old state in Tower

In case you are using the Tower Git client, you can simply right-click the revision you want to return to and create a new branch:

Thursday, 27 December 2018

GIT: How can I undo the last commit?

First, before we bring the big guns in, let's make sure you really need them. Because in case you just want to edit your last commit, you can simply use Git's amend feature. It allows you to correct the last commit's message as well as add more changes to it. If that's what you want to do, read more about amend.

Undoing the Last Commit

However, of course, there a tons of situations where you really want to undo that last commit. E.g. because you'd like to restructure it extensively - or even discard it altogether!
In these cases, the "reset" command is your best friend:
$ git reset --soft HEAD~1
Reset will rewind your current HEAD branch to the specified revision. In our example above, we'd like to return to the one before the current revision - effectively making our last commit undone.
Note the --soft flag: this makes sure that the changes in undone revisions are preserved. After running the command, you'll find the changes as uncommitted local modifications in your working copy.
If you don't want to keep these changes, simply use the --hard flag. Be sure to only do this when you're sure you don't need these changes anymore.
$ git reset --hard HEAD~1

TIP

Undoing Multiple Commits

The same technique allows you to return to any previous revision:
$ git reset --hard 0ad5a7a6
Always keep in mind, however, that using the reset command undoes all commits that came after the one you returned to:

GIT: Resetting the working tree based on a commit

31.1. Checkout based on commits and working tree

git checkout, based on commit ID
You can check out arbitrary revisions of your file system via the git checkout command followed by the commit ID. This command will reset your complete working tree to the status described by this commit.
The commit ID is shown if you enter the git log command.
The following command shows the log.
# displays the commit history of the repository
# which contains the commit ID, author, message etc.
git log
The following listing shows an example output of a Git log command.
commit 046474a52e0ba1f1435ad285eae0d8ef19d529bf
Author: Lars Vogel <Lars.Vogel@gmail.com>
Date:   Wed Jun 5 12:13:04 2013 +0200

    Bug 409373 - Updates version number of e4 tools

    Repairs the build

commit 2645d7eef0e24195fc407137200fe7e1795ecf49
Author: Lars Vogel <Lars.Vogel@gmail.com>
Date:   Wed Jun 5 12:00:53 2013 +0200

    Bug 409373 - Updates version number of e4 CSS spy features

31.2. Example: Checkout a commit

To checkout a specific commit you can use the following command.
# checkout the older revision via
git checkout [commit_id]

# based on the example output this could be
git checkout 046474a52e0ba1f1435ad285eae0d8ef19d529bf

# or you can use the abbreviated version
git checkout 046474a5
If you checkout a commit, you are in the detached head mode and commits in this mode are harder to find after you checkout another branch. Before committing it is good practice to create a new branch. See Detached HEAD for details.

GIT: Resetting changes with git reset


26.1. Finding commits that are no longer visible on a branch

If you reset the branch pointer of a branch to a certain commit, the git log commands does not show the commits which exist after this branch pointer. For example assume you have two commits A→ B, where B is the commit after A. You if you reset your branch pointer to A, the git log command does not include B anymore.
Commits like B can still be found via the git reflog command.

GIT: Using Git reset

25.1. Moving the HEAD and branch pointer

Sometimes you want to change the commmit your branch pointer is pointing to. The git reset command allows you to manually set the current HEAD pointer (and its associated branch) to a specified commit. This is for example useful to undo a particular change or to build up a different commit history.
Git reset
All commits which were originally pointed to by the HEAD pointer and the commit pointed to by HEAD after the reset, are reseted, e.g., not directly visible anymore from the current HEAD and branch pointer.
Via parameters you can decide what you happen to the changes in the working tree and changes which were included in the commits between the original commit and the commit now referred to by the HEAD pointer. As a reminder, the working tree contains the files and the staging area contains the changes which are marked to be included in the next commit. Depending on the specified parameters the git reset command performs the following:
  1. If you specify the --soft parameter, the git reset command moves the HEAD pointer. Changes in the working tree will be left unchanged and all changes which were commited included in commits which are reseted are staged.
  2. If you specify the --mixed parameter (the default), the git reset command moves the HEAD pointer and resets the staging area to the new HEAD. Any file change between the original commit and the one you reset to shows up as modifications (or untracked files) in your working tree. Use this option to remove commits but keep all the work you have done. You can do additional changes, stage changes and commit again. This way you can build up a different commit history.
  3. If you specify the --hard parameter, the git reset command moves the HEAD pointer and resets the staging area and the working tree to the new HEAD. This effectively removes the changes you have done between the original commit and the one you reset to.
Via parameters you can define if the staging area and the working tree is updated. These parameters are listed in the following table.
Table 2. git reset options
Reset
Branch pointer
Working tree
Staging area
soft
Yes
No
No
mixed (default)
Yes
No
Yes
hard
Yes
Yes
Yes
The git reset command does not remove untracked files. 

25.2. Not moving the HEAD pointer with git reset

If you specify a path via the git reset [path] command, Git does not move the HEAD pointer. It updates the staging area or also the working tree depending on your specified option.