Git Learning

This post is to keep my git knowledge at one place. It consists of the commands used frequently and will evolve as I discover more about git.

Concepts

Working Areas
It’s useful to visualize the workspace and the best diagram for this is Oliver Steel Git Data Transport Commands.

Git data transport commands

For more information checkout Oliver blog

As per diagram git keeps your files at these distinct places.
Workspace: Your local directory where physical files are kept:
Index: Staging area holds the files for next commit.
Local Repository: Committed files ready to be pushed to remote.
Remote Repository: Contains commits from all users.

Markers
HEAD: Reference to the last commit in the currently checked-out branch. There is a small exception to this, which is the detached HEAD. A detached HEAD is the situation you end up in whenever you check out a commit (or tag) instead of a branch. In this case, you have to imagine this as a temporary branch without a name; so instead of having a named branch reference, we only have HEAD. It will still allow you to make commits (which will update HEAD), so the above short definition is still true if you think of a detached HEAD as a temporary branch without a name.

^: Parent of the commit.
HEAD^: First parent of the tip of the current branch. HEAD^1-: Same as HEAD^, first parent of the tip of the current branch. Only useful in merge commits. The first parent is the branch you were on when you merged. _HEAD^2-: Second parent of the tip of the current branch if HEAD was a merge, otherwise illegal. Second parent is the commit on the branch that you merged in. _HEAD^^: 2 commits older than HEAD. Not the same as HEAD^2. HEAD^^ means the first parent of the first parent (shorthand for HEAD^1^1). Confusing! Better use tilda.

~: Always means first parent. so HEAD~2 == HEAD^^ HEAD~: 1 commit older than HEAD. Equivalent to HEAD^ (HEAD’s first parent) HEAD~2: 2 commits older than HEAD. Equivalent to HEAD^^ (HEAD’s first parent’s first parent). HEAD~3: Equivalent to HEAD^ (HEAD’s first parent’s first parent’s first parent)

@{}: Reflog short names HEAD@{2}: view the second prior value of the HEAD of your repository

^ and ~ operators can be used for other references such as commits. Commit and Head are usually interchangeable.

Git Commands

Setup and Init


git config --global user.name “[firstname lastname]”
# set a name that is identifiable for credit when review version history

git config --global user.email “[valid-email]”
# set an email address that will be associated with history

git config --global color.ui auto
# set automatic command line coloring for Git for easy reviewing

git init
# initialize an existing directory as a Git repository

git clone [url]
# retrieve an entire repository from a hosted location via URL

Staging


git status
# show modified files in working directory, staged for your next commit

git status -s
# shorter version of status

git add [file]
# add a file as it looks now to your next commit (stage)

git reset [file]
# unstage a file while retaining the changes in working directory

git diff
# diff of what is changed but not staged

git diff --staged
# diff of what is staged but not yet committed

git commit -m “[descriptive message]”
# commit your staged content as a new commit snapshot

Branching


git branch
# list your branches. a * will appear next to the currently active branch

git branch -r
# list remote branches

git branch [branch-name]
# create a new branch at the current commit

git checkout [branch-name]
# updates the files in the working directory to match the version stored in that branch

git checkout -b temp-branch-name commit-hash
# create a temp branch to avoid having detached head

git merge [branch]
# merge the specified branch’s history into the current one

git log
# show all commits in the current branch’s history

Sharing Changes


git remote add [alias] [url]
# add a git URL as an alias

git remote -v
# list remote alias

git fetch [alias]
# fetch down all the branches from that Git remote

git merge [alias]/[branch]
# merge a remote branch into your current branch to bring it up to date

git push [alias] [branch]
# transmit local branch commits to the remote repository branch

git pull
# fetch and merge any commits from the tracking remote branch

git log
# show all commits in the current branch’s history

Discarding Local Changes


git reset --soft [commit]
# resets HEAD back to another commit, does not touch the staged or the working directory at all (this leaves all your changed staged and marked for commit)

git reset [commit] (default parameter --mixed applied. if commit omitted resets to last commit)
# resets HEAD back to another commit, resets the staged to match it, does not touch the working directory (changed files are preserved but not marked for commit)

git reset --hard [commit]
# resets HEAD back to another commit, resets the staged to match it, and resets the working directory to match it as well (any changes to tracked files in the working tree are discarded)

git reset [commit] [filepath]
# reset A specific file, commonly used with HEAD rather than an arbitrary commit

git commit -a -m "saving my work"
git branch my-saved-work
# saving work to new branch before reseting
 
git fetch origin
git reset --hard origin/[remote]
# reset branch to exactly match the remote branch

git clean -f -d
# remove untracked, forced and remove directories

git clean -fxd :/
# cleans untracked and ignored files through the entire repo (without :/, the operation affects only the current directory)

Discarding Pushed Changes


git revert [commit] 
# create a new commit that undoes all changes.

git revert [commit] 
# create a new commit that undoes all changes.

git revert [oldest_commit_hash]..[latest_commit_hash]
# would result in separate commits 

git revert --no-commit [oldest_commit_hash]
git revert --no-commit [latest_commit_hash]
git commit -m "the commit message"
# would result in one combined commit 

git revert -m 1 
# with ‘-m 1’ git will revert to the first parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in 
</code></pre>


git reset HEAD^ --hard
git push origin -f
# will result in rewritting the history 
**Exploring**

git log
# show the commit history for the currently active branch

git log branchB..branchA
# show the commits on branchA that are not on branchB

git log --follow [file]
# show the commits that changed file, even across renames

git diff branchB...branchA
# show the diff of what is in branchA that is not in branchB

git show
# show various objects such as commit log

git show [SHA]
# show any object in Git in human-readable format
**Saving temp work**

git stash
# save modified and staged changes

git stash list
# list stack-order of stashed file changes

git stash pop
# write working from top of stash stack

git stash drop
# iscard the changes from top of stash stack