frequently forgotten git commands

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

rebase or merge?

in progress

.gitignore

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

source

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

source

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

source

an unsung hero; git submodules

source

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
repos:
  - repo: https://github.com/psf/black
    rev: 22.10.0
    hooks:
      - id: black
  - repo: https://github.com/PyCQA/flake8
    rev: 5.0.4
    hooks:
      - id: flake8
        args: ["--max-line-length=89", "--ignore=E731,W503,E203"]
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: "v0.982"
    hooks:
      - id: mypy

and install the hook using

pre-commit install

hooks are great.

pre-commit source