some useful git commands
Tags: git, programming, productivity, beginners
Published: 2022-02-21 09:43:17

Some useful [`git`](https://git-scm.com/) commands:

## git log

`git log` shows the recent history from the current commit. It might be outdated, if we did not synchronize our local repository with the origin (`git pull`) or if we checked out an older commit or tag on purpose.

The history shows the commit hashes, committer, commit date, and commit message.

`git log -p` shows the same history plus the detailed diff of the changed files in each commit.

`git log -p mydir` restricts the same command to the `mydir` directory. Useful in a repository that includes build artifacts that we don't want to see in the diff.

`git log --all --decorate --oneline --graph` shows the latest history in a slightly graphical way, adding line graphics to show where feature branches have been forked and merged.

## git diff

To see the latest changes that have not been added to the upcoming commit yet, use `git diff`.

If `git diff` does not show anything, there might still be some changes already *staged* for commit.

`git diff --cached` shows us those changes.

## git reset

`git reset` *unstages* those changes. The files are still changed, and we can see the changes in `git diff` again.

`git reset --hard` causes to *undo* those changes. After a hard reset, our changes will be gone! We might still be able to undo our undo using the local undo history of our code editor.

We can also do a hard reset to a certain commit or branch head, like 
`git reset --hard origin/develop`.

But if we try do to this for a single file, git will tell us that it "cannot do hard reset with paths". Well, it can, but only if we use a different syntax:

`git checkout -- a/changed/file.txt` will discard our latest changes.

## git status

While many commands include more or less detailed status information about our current local repository, we can also ask `git` where we are and if there are upcoming changes not yet committed.

```
git status

On branch example
nothing to commit, working tree clean
```

## git branch, git tag

`git branch` lists all local branches.

`git tag` lists all local tags.

`git tag "v1.2.3"` sets a new tag `v1.2.3`

Don't forget: after setting a new tag, we might need to push them explicitly:
`git push --tags`

## searching on the command line

We can use [`grep`](https://manpages.org/grep) (not specific to git, but also with git, we can use the pipe symbol `|` to [chain shell commands](https://en.wikipedia.org/wiki/Pipeline_(Unix))) to narrow down our selection:

```
git branch | grep error
```

... will only list all local branches that contain the word `error` in their names.

## git merge, git rebase

Merge and rebase can get complicated even without conflicts, and often, merges are done in a workflow using environments like GitHub or GitLab, at the end of a successful code review. All of that goes beyond this short post.

But there is a handy idiom to get the latest changes from a `main` or `development` branch into the current feature branch, that I use quite often:

`git rebase develop` will change the order of commits to make it look like all of our work in the current feature branch was done after the latest commit in `develop`.

## - means the previous branch

If you like the command line, but you don't want to type long branch names all of the time, you hopefully use code completion. But there is another useful abbreviation to save a lot of typing and mistyping: `-` means the previous branch.

So if I change branches to do a `merge` or `rebase`, I can use `-` instead of the last branch name:

```
git checkout develop
git pull
git checkout featurebranch
git commit -am "latest changes"
git checkout -
git merge -
```

The last two lines actually mean the same as

```
git checkout develop
git merge featurebranch
```

If you *don't* like the command line, you probably don't like the [`vi`](https://www.vim.org) editor either, so you might want to change the default editor for entering commit comments and solve conflicts.

`git config core.editor notepad` would set `notepad` as git's default text editor.

You can also add single line commit messages using the `-m` option like this:

`git commit -m "fix typo in README" README.md`

## use the tools that help you

Don't get afraid or overwhelmed by all the command line examples! There is good support for `git` version control in modern editors and IDEs like VSCode or PhpStorm, and you should use the tools that help you boost your productivity.

But if you prefer the simplicity and ubiquity of command line (like I do) over graphical user interfaces (that might change with every release of your favorite IDE), knowing some command line options by heart can help to stay productive as well. I don't write my code in `vi`, and I use GitHub and GitLab, but it has helped me a lot to know how to use `git` on the command line.