In my day to day job I use Git very frequently, but I’ve never spent the time to properly get my head round the more complex parts, instead relying on muscle memory and StackOverflow for those occasions that I get stuck.
I decided to read parts of Pro Git (git-scm.com/book/en/v2), going back to basics to learn a bit more about the internals and more advanced features of Git, and to solidify my understanding of this powerful but at times opaque tool.
Useful aliases can be found at the bottom of this page
git config --global --edit to edit the global Git config file, --system for the system config (/etc/gitconfig), --local for the repository local file (which is the default config file Git will read from - stored in .git/config in a repository)
git config --list --show-origin to see the full list of config parameters and their originsgit config --global core.editor vim to set the editor for commit messages and stuffgit status command is used to see the state of files in your repository
git status -s for a shorthand easier to parse status
git add <file> to add files to the staging area (duh). Specifying a directory will add all the files in that directory/ to avoid recursivity (patterns are recursive by default) (basically specifying the project root) - ending with / specifies a directory!, e.g. if you ignore *.a but you want lib.a you’d use !lib.a** to match nested directories, e.g. a/**/z matches a/b/z, a/b/c/z etc.git diff with no args shows files changed but not stagedgit diff --staged shows staged files (--cached is a synonym)git commit -a skips the need to git add .git rm is used to remove a file from the staging area, and will also remove it from the working directorygit rm --cached (or --staged) removes a file from the staging area without removing it from the working directory
git rm commands but must make sure to include a \ before a * to disable shell filename expansiongit loggit log is used to view the commit history in reverse chronological order
-p to show the difference (patch output) in each commit-n for a number n to show the last n commits--pretty is used to change the log output, e.g. --pretty=oneline prints single line logs with the hash and commit message. A custom format can also be created with --pretty=format: (see man page for more)--graph shows the branch and merge history--author and --grep to filter for specific authors and for specific keywords in commit messages respectively-S (pickaxe) takes a string and shows only commits that changed the number of occurrences of that string (e.g. adding or removing references to method calls)--no-merges to hide merge commits-- to separate from other options. In fact it is the default last argumentgit commit --amend (without changes staged it will just allow changing the commit message)git reset HEAD <file>git checkout -- <file>, Git will replace your working directory version with the last staged or committed versiongit restore is an alternative to git reset
git restore --staged <file>git restore <file> (rather than checking out the file)git remote -v shows the remotes you have configured for the repository. origin is the default name Git gives the server you cloned from, but remotes can have different names if desired.
git remote add <shortname> <url>git fetch <remote>, e.g. git fetch origin
origin’s main branch is then accessible locally as origin/maingit fetch <remote>
git pull can be used to fetch and merge a remote branch into your current local branch, if you have your current branch set up to track a remote branch
git clone sets up the local main branch to track the remote main branchpull is a fetch and merge operation in onegit push <remote> <branch> - git clone again sets up the origin remote and main branch automaticallygit remote show <remote shortname> is good for seeing the configuration for a specified remote
git tag to list tags, -l "v1.8.*" to find specific tags with a wildcard (requires -l)git tag -a v1.4 -m "This is v1.4" to create a new annotated tag with a messagegit show v1.4 to show the information about a taggit tag v1.4 without -a creates a lightweight tag - lightweight tags can be thought of as just a commit hash stored in a file, no more information is keptgit tag -a v1.4 <commit hash> - can be a partial commit hash as long as it’s uniquegit push origin v1.4, similar to pushing to a remote branch
git push origin --tags to push all local tagsgit push origin --delete <tagname>git checkout <tagname> to checkout a tag, this puts you in a detached HEAD state
git checkout -b <branchname> <tag>git branch <branch> creates a new branch, git checkout <branch> switches you to that branch (changes HEAD to the new branch pointer)
checkout and the files will be restored to the state they were in at that the point of branchinggit log --oneline --decorate --graph --all will print the history of commits, showing branches and history divergence
Various useful aliases
git config --global alias.unstage 'reset HEAD --'git config --global alias.last 'log -1 HEAD'