Git Notes

See git flight rules for useful, detailed notes.

My notes here are things I like to remind myself of regularly. You will recognise many of them, but look carefully for some useful tips!

Logs

git shlg      # pretty, shorter log
git lg        # pretty, longer log
git pl        # pretty log
git diff --stat <ref>     # bar chart of changes

These log alternatives are aliases:

alias.shlg log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
alias.lg log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
alias.pl log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short

Other useful commands

git blame filename   # show who made what changes to the file
git reflog

See git reflog | Atlassian Git Tutorial and Git - git-reflog Documentation

Tig

But, possibly the best tool for viewing git history is tig. You can install via homebrew or your package manager of choice. It’s an ncurses-like commit browser. Try tig --all to check it out, and hit h for interactive help.

Merging

[~/blog/main]> git merge --no-ff feature/tag_indices

Merge the named branch onto the current branch I prefer to no-ff a merge so that it’s clear what set of commits were part of a feature.

Rebasing and Git History Manipulation

[~/blog/feature/tag_indices]> git rebase main

Unwind the current branch and replay all the changes onto the tip of the named branch.

Interactive Rebasing

# git rebase -i <ref to root of rebase>

[~/blog/feature/tag_indices]> git shlg
* 59762e1 - Oops I forgot a file - Mark Coleman (HEAD -> feature/tag_indices)
* 9eb6dd3 - fixup - Tidy up whitespace - Mark Coleman
* ca1fc7b - Add super new functionality - Mark Coleman
* b9a66a9 - Create new pages - Mark Coleman

git rebase -i b9a66a9
> pick ca1fc7b - Add super new functionality
> pick 9eb6dd3 - fixup - Tidy up whitespace
> pick 59762e1 - Oops I forgot a file

Then, pick, edit, fixup or squash (onto previous) commits. Delete the line to remove a commit entirely.

You can also change the order of commits. This may cause conflicts. Editing allows you to further --amend the message, or split a commit in two.

Splitting A Commit

To split the last commit into multiple commits

git reset HEAD~

Now add commits the regular way.

To split a commit further in the history:

pick 123abc bunch of changes
edit a1b2c3 commit you want to split
pick abc321 another commit to leave as-is

Once git has reached the point that you’ve chosen to edit, you can adjust the commit as before and then continue:

  git reset HEAD^
  git add <half the files>
  git commit
  git add <other half>
  git commit
  git rebase --continue

I also like to use git add -p to interactively add commit segments. Also, see the vim tool, Vim-Fugitive. That is very useful.

To interactively add segments of a new file, you need git to start tracking the new file first.

$ git add -N filename

Misc

Retrieving a different version of a file

To check out a different version of a file, so that you can compare it with the current version:

$ git show framework:cv.md > old_cv.md

Moving a branch pointer

$ git branch -f name_of_branch_to_move commit_ref_to_point_to

Pushing a branch somewhere else

$ git push <remote> <branch>
$ git push <remote> <local_branch>:<remote_name>

Git Cherry

$ git cherry tag_a tag_b -v

So, concentrate on the + commits. They are the ones missing from tag_a.

Git Stash

$ git stash save "message"
$ git stash list
$ git stash pop <index>
$ git stash apply  # doesn't remove stash)
$ git stash drop <index>

git stash show will show a very brief list of files that were saved in the stash

git stash show -p will show the changes vs the current HEAD

You can specify the stash you wish to compare: git stash show -p stash@{2}

To set an upstream tracking branch:

$ git push -u <remote> <branch>
$ git branch -vv          # show tracking branches
$ git checkout --track remote/branch   fetch, checkout and track a remote branch
$ git branch -u remote/remote_branch_name     # track current branch at specified remote branch

Commit Manipulation

To create a commit with a specified date:

$ git commit --date "now"
$ git commit --date "2019-12-30"

Git actually has two dates associated with each commit: the author date and the committer date. To change commit history, you can do an interactive rebase, set the commits to edit, then, to change both dates:

$ GIT_COMMITTER_DATE="2017-10-08T09:51:07" git commit --amend --date="2017-10-08T09:51:07"
$ git rebase --continue

Bear in mind that this changes all the commit hashes, so you’d have to force push back a public branch and deal with all the consequences.

Github CLI useful additions

Github hub extensions is being superseded by github cli See the (rather terse) manual for full details.

gh auth login             # authorise gh cli
gh repo view --web        # open this repo's github page

Forking and creating a PR

gh repo fork account/name
gh repo clone account/name

git fetch upstream
git co -b new_token/pocket

git pr create --fill       # create a pr for your forked project and pre-fill from commit messages
git pr create --repo OWNER/REPO    # create the pull request in the named upstream repo
Tagged: | git | github | software-development |
Cover Image: Brett Jordan, via Unsplash