How I Use Git

obligatory XKCD

I've used git since at least 2013, but only around 2019 after stumbling upon The Git Parable did I take time actually learn.

How I Learned Git

  1. (optional) use git clone a bunch without really understanding what's going on. Contribute to coworkers' projects (git add/commit/push, then create an MR in GitHub).

  2. read The Git Parable (20 mins).

    I read this 1 section at a time over a few nights to allow time to digest what I read. Read a section, then go poke around some repository to see if you can make sense of what you read.

  3. iff you intend to use Git collaboratively, review a few Git Workflows.

    for non-software projects using Git, I prefer the Centralized Workflow.

    for collaborative software projects, you'll often see the Forking Workflow (e.g. WordPress).

    1. The Centralized Workflow is a great Git workflow for teams transitioning from SVN. The result is a perfectly linear history. Make local changes, fetch, rebase, resolve conflicts, push.
      "... I want to add my changes to what everyone else has already done.” 

    2. Feature Branch Workflow... means the master branch will never contain broken code. You'll push your changes to a remote feature branch, then create pull requests to merge back in to master.
      "... feature development should take place in a dedicated branch instead of the master branch. This encapsulation makes it easy for multiple developers to work on a particular feature without disturbing the main codebase."

    3. Gitflow is ideally suited for projects that have a scheduled release cycle and for the DevOps best practice of continuous delivery. 
      "The Gitflow Workflow defines a strict branching model designed around the project release. This provides a robust framework for managing larger projects."

    4. Forking Workflow ... is a distributed workflow that provides a flexible way for large, organic teams (including untrusted third-parties) to collaborate securely.
      "This allows the maintainer to accept commits from any developer without giving them write access to the official codebase."

  4. teach someone else!

    I held a series of 1-hour Git crash-courses with my team of Linux system admins. The audience's prior experience ranged from new Linux sys-ad with no Git exposure, to senior tech leads who had used git clone a bunch without really understanding. The 1-hour workshop finished with all attendees closing their own Issue by submitting a Merge Request to our GitHub project.

Reference

I refer to Atlassian's Git docs often, especially git-rebase. Their graphics really help my understanding of, for example, git rebase main

Git Config

Command Aliases

Reading Logs

List commits on one-line using graph layout and pretty colors.

(credit to https://stackoverflow.com/a/9074343)

# git l - last 20 commits on current branch
alias.l=log -n 20 --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ad)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'
# git lg - last 50 commits, all branches
alias.lg=log --all --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ad)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'

This pairs well with shell aliases:

alias gl=git l
alias glg=git lg

Common Tasks

documented here so I don't have to go searching every time...

Remove a File from Previous Commit

I've accidentally committed a file that wasn't ready yet, but I want to keep the other files and changes in the commit.

(credit to https://stackoverflow.com/a/15321456)

# "un-commit" the last commit, leaving changes as "changes to be committed"
git reset --soft HEAD^

# reset or "un-stage" the unwanted file to leave
git reset HEAD path/to/unwanted_file

# finish by re-committing, optionally re-using/editing a commit message
git commit [-c <ORIG_HEAD>]

Reset Author on Several Commits

Be sure to actually configure your user.name and user.email before you try to fix it!

(adapted from https://stackoverflow.com/a/25815116)

git config --global user.name "Alan Turing"
git config --global user.email "[email protected]"
# rebase to 3-commits-ago (HEAD^^^), and reset-author on each commit
git rebase -i HEAD^^^ -x "git commit --amend --reset-author --no-edit"