frequently forgotten git commands

A collection of links and guides for getting out of all sorts of git trouble.

rebase or merge?

in progress


setup a gitignore file

removing last commit and rewriting history (careful!)

Use the reset command. First undo the local commit

 git reset HEAD^ 

Then, force push the reverted local commit to the remote git repository with

 git push origin +HEAD 

Note: This will overwrite the commits that you reverted and they will no longer exist.

revert unstaged changes


For all unstaged files in current working directory use:

git restore .

For a specific file use:

git restore path/to/file/to/revert

That together with git switch replaces the overloaded git checkout, and thus removes the argument disambiguation.

If a file has both staged and unstaged changes, only the unstaged changes shown in git diff are reverted. Changes shown in git diff –staged stay intact.

revert single file back to specific commit or HEAD

reset both the working copy and the state in the Git index to that of HEAD:

git checkout HEAD -- my-file.txt


git diff a file between commits

From the git-diff manpage:

git diff [–options] [--] [...] For instance, to see the difference for a file "main.c" between now and two commits back, here are three equivalent commands:

git diff HEAD^^ HEAD main.c
git diff HEAD^^..HEAD -- main.c
git diff HEAD~2 HEAD -- main.c


an unsung hero; git submodules


pre- and post-commit hooks

With Git, you can trigger custom scripts through certain actions. These actions are grouped into two different sets of hooks: client- and server-side. Client-side hooks are triggered by commiting, merging, etc. while server-side hooks run on network operations (e.g. receiving pushed commits).

hooks are stored under .git/hooks, which is automatically populated with some hooks when initializing git repo with git init. Hooks can be written with any language (ruby, python, etc.) so long as they are in properly named and executable scripts.

Enable a hook script by putting it in a file in the hooks subdirectory, naming it appropriately (no extensions!), and making it executable. After that, it will be called when ever the corresponding triggering action is performed. For a list of all major hook filenames, check the source below.

pre-commit hooks are often part of a proper workflow to ensure that nothing is overlooked when commiting. Pre-commit hooks can check whether e.g. the code is properly formatted, the linter succeeds, and/or all test cases pass. Note that the pre-commit hook can be bypassed using git commit –no-verify. A nice framework for managing/maintaining pre-commit hooks is provided by pre-commit(check links). After installing the framework, create a file named .pre-commit-config.yaml and configure the hook as you please. An example config file for python projects:

fail_fast: true
  - repo:
    rev: 22.10.0
      - id: black
  - repo:
    rev: 5.0.4
      - id: flake8
        args: ["--max-line-length=89", "--ignore=E731,W503,E203"]
  - repo:
    rev: "v0.982"
      - id: mypy

and install the hook using

pre-commit install

hooks are great.

pre-commit source