Skip to content

Instantly share code, notes, and snippets.

@shahrokh-bahtooei
Created April 20, 2022 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shahrokh-bahtooei/392e8189670830a550ced99513c70de0 to your computer and use it in GitHub Desktop.
Save shahrokh-bahtooei/392e8189670830a550ced99513c70de0 to your computer and use it in GitHub Desktop.
A cheat sheet on Git commands

License: MIT

A cheat sheet on Git commands introduced by Corey Schafer's Git Tutorials and some awesome blog posts.

Contents

Basic commands

Defining user

git --version
git config --global user.name "first_name last_name"
git config --global user.email "some_number_github_offers+my_github_id@users.noreply.github.com"

git config --list

Modifying exposed emails in previous commits in a batch-process way

git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="New Name Value"
NEW_EMAIL="correct@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

Resource: How can I change the author name / email of a commit? # Using git filter-branch

Modifying email just in the last commit

git commit --amend --author="first_name last_name <some_number_github_offers+my_github_id@users.noreply.github.com>"

Storing GitHub credentials in macOS keychain

git config --global credential.helper osxkeychain

"The next time you clone an HTTPS URL that requires authentication, Git will prompt you for your username and password. When Git prompts you for your password, enter your personal access token (PAT) instead. Once you've authenticated successfully, your credentials are stored in the macOS keychain and will be used every time."

Resource: Caching your GitHub credentials in Git

Initializing git

ls -la
git init
ls -la
git status
touch .gitignore

...adding ignored files...

git add .gitignore
git status

Adding files to staging area

git status
git add my_file
git add -A // all except ignored ones
git status

Removing files from staging area

git status
git reset my_file
git reset // all files
git status

Doing the first commit

git add -A
git commit -m "Initial Commit"
git status
git log

Cloning a remote repo

git clone ../remote_repo.git .
git clone https://github.com/my_github_id/remote_repo.git .

Viewing info about remote repo

git remote -v
git branch -a

Pushing changes

git diff
git status
git add -A
git commit -m "My new feature description"
git pull origin master
git push origin master

Common workflows

Adding a feature

  1. Create a branch for desired feature:
git branch calc_divide
git checkout calc_divide

…writing code…

commit -m "Develop function calc_divide"
  1. After commit, push branch to remote:
git push -u origin calc_divide
git branch -a
  1. If other people also approved, merge branch:
git checkout master
git pull origin master
git branch --merged
git merge calc_divide
git branch --merged
git push origin master
  1. Delete the merged branch:
git branch --merged
git branch -d calc_divide
git branch -a
git push origin --delete calc_divide

Syncing a fork

  1. Configure an upstream for the local repo:
git remote -v
git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git
git remote -v
  1. Sync the local repo with the upstream:
git fetch upstream
git checkout master

then either

git merge upstream/master

or

git rebase upstream/master
  1. Push master from the updated local repo to origin at GitHub:
git push origin master

or

git push -f origin master

Commit message format

  1. title (imperative mood) <= 50 chars
  2. blank line
  3. body, each line <= 72 chars, blank line between paragraphs
    • the reasons why you made the change in the first place
    • the way things worked before the change
    • what was wrong with that
    • the way they work now
    • why you decided to solve it the way you did
  4. Resolves: #IssueNumber

How to fix mistakes

Fixing the last commit

Changing message

git commit --amend -m "New commit message"

It changes the commit hash, so the git history changes too. It’s good when commits are not yet shared with people. Otherwise, use git revert.

Adding files

git add my_missed_file
git commit --amend
git log --stat

Press :wq to save the commit message prompt and exit it.

Grabbing a commit from another branch

Let's grab the last commit from master to my-feature-branch:

git checkout master
git log

Copy a beginning piece of the hash belonging to the last commit:

git checkout my-feature-branch
git cherry-pick piece_of_hash

Removing a commit (reset)

Soft

It keeps our changes in the staging area.

git reset --soft piece_of_hash

Mixed

It keeps our changes in the files, but it doesn't add them to staging area.

git reset piece_of_hash

Hard

We get rid of all the changes after the commit!

git reset --hard piece_of_hash

Undoing while preserving commit history

It reverses the effects of some earlier commits via a new undoing commit. That way, it adds to the commit history; it neither modifies nor deletes it. Thus, it's a safe way of undoing the commits that have already been shared.

git log
git revert piece_of_hash
git log
git diff piece_of_hash piece_of_new_commit_hash 

Discarding changes in the working directory

git checkout -- .

or

git reset --hard

Getting rid of untracked files

It deletes all untracked directories and files!

git clean -df

Recovering deleted changes

It stores all commits even the lost ones for around 30 days in trash. It can be a life-saver!

git reflog

It shows commits in the order of when you last referenced them. Copy the hash of the commit that you wish to recover.

git checkout piece_of_hash 
git log
git branch restoring-branch
git checkout restoring-branch
git log

A Comparison of reset, checkout, and revert

Command Scope Common use cases
git reset Commit-level Discard commits in a private branch or throw away uncommitted changes
git reset File-level Unstage a file
git checkout Commit-level Switch between branches or inspect old snapshots
git checkout File-level Discard changes in the working directory
git revert Commit-level Undo commits in a public branch
git revert File-level (N/A)

Resource: Git Reset vs Revert vs Checkout reference

How to stash

Saving the changes temporarily

It allows us to switch branch without committing them.

git stash save "Worked on the functionality blah"
git stash list
git checkout other-branch

Bringing back the changes

git checkout bloh-branch
git stash list

Apply and then delete:

git stash apply stash@{some-id}
git stash drop stash@{some-id}

Apply and delete simultaneously:

git stash pop

Deleting all stash

It deletes current unsaved changes too!

git stash clear

How to rebase

The golden rule: rebase only your un-forked branches!

A comprehensive resource: Merging vs. Rebasing

Rebasing all feature commits on the tip of master

It results in a perfectly linear history :)

All at once

git checkout feature
git rebase master

Step by step (with interactive rebase)

git checkout feature
git rebase -i master

Force-Pushing

When the commit history on your remote repo is different from your rebased local one, you have to force-push your local changes to the remote—which irreversibly overwrites the remote history!

git checkout feature

# Be very careful with this command!
git push origin feature --force

Interactive Rebase

Modifying the last 3 commits

git rebase -i HEAD~3

Finding the sub-branch root and modifying the whole branch

git merge-base feature master
git rebase -i piece_of_hash

Modifying fundamentally from the root commit

git rebase -i --root

Rebasing all my shared-feature commits on the tip of the recently updated remote shared-feature

git checkout shared-feature
git pull origin shared-feature --rebase

Resource: How to Write a Git Commit Message

Where to store .gitignore

  • Global (for cache files)
nano ~/.gitignore_global
  • Local (for additional files that are specific to the project and that should be ignored on other computers too)
nano ./.gitignore

How to use git diff for notebooks

  • Usual
git diff
  • Graphical
nbdiff-web

Resource: Version control integration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment