There many GUI tools that help with version control, but I prefer terminal commands for most git-related things.
The changes you make typically go through the following steps:
- Working directory (changes haven't been staged or committed)
- Staged (you've run
git add
and now have changes staged. Stage is also referred to as "Index" or "cache") - Committed (you've run
git commit
and your staged changes have been added to a local commit) - Pushed to remote (you've run
git push
and your commit now exists in the remote repo) - Merged to main/master (you've merged your branch into the main/master branch on github)
Other terms:
- Stage (also called index or cache) - You add things to the stage with
git add
. And then when you rungit commit
, it pulls changes from the stage into a commit. - Commit - One unit of changes made to a repo (can include multiple files). You refer to these with their hash value.
- Tag - A human friendly/readable value that gets assigned to a specific commit of a repo.
- HEAD - where your git is "pointing" currently. This could be a specific Tag/Commit or Branch.
- Branch - A named set of zero or more commits. When you have a branch checked out and you
git commit
your changes, the HEAD automatically moves to this new commit. This is the fundamental difference between a branch and a tag.
These are roughly in the order that you'd need them. And then there are some less-common use-cases at the end as well.
Pull down a repo from github to your local computer:
git clone <repo link>
Pull the latest changes made to this repo since you last cloned/pulled it:
git checkout main # assuming this is the name of your main branch
git pull
Create a branch and check it out:
git checkout -b <name_of_branch_to_create>
git checkout <name_of_existing_branch>
Add files you've updated to the index/stage/cache so you can eventually commit and push them to the remote repo:
git add . # adds all files
git add <path_to_file> # adds a specific file
git add <path>/* # adds all files within a specific path
Sometimes, you might only want to add
parts of a file:
git add -p <file or . or path>
The -p
flag will open up a dialog in your terminal that lets you add specific portions ("hunks") of your changed file(s). Docs for -p flag and other add flags.
To remove things from the index/stage/cache:
git restore --staged . # unstage everything
git restore --staged <file or path> # unstage specific things
Note: make sure you use the --staged
flag or you might delete all of your work that hasn't been committed.
What files have been changed in the local working directory and are/aren't staged yet:
git status
Specifically which lines in which file(s) have changed:
git diff # defaults to all unstaged, changed lines in non-new files
git diff --cached # changed lines in the stage/cache/index
git diff <file path>
Create a temporary "stash" of your changes that you can come back to later:
git stash -m "<some message to describe the stash>"
To see a list of the stashes you've... stashed:
git stash list # see all stashes
git stash list | head -n 10 # see just the last 10 stashes
And then when you want to resume working on something you stashed earlier:
git stash pop # apply most recent stash and delete it from stash list
git stash apply 0 # apply most recent stash; don't delete it
You've added the changes you want to commit, now you are ready to commit and push them:
git commit -m "<Enter a commit message to describe your changes>"
Un-commit the last commit:
git reset --soft HEAD~1
The --soft
flag will keep the changes that you had previously committed. The HEAD~1
will undo just the latest commit you've created. You can use HEAD~2
to undo the last two commits, and so on.
The changes will now exist in your stage/index/cache.
Push your local commits to the remote repo
git push
TODO:
- rebase
- merge
TODO:
git bisect
: semi-manually identify when a specific thing changed in the codebase using binary search- git worktrees: set up multiple copies of the same repo where you can have different branches checked out. This is useful for quickly fixing bugs when you're already working on some changes without having to
stash
or create a dummy/temp commit. - cherry pick: you've created a commit on one branch, but you want to pull it into a different branch
- dealing with merge conflicts... not sure what all to say about this one. I prefer commands over IDEs for everything except this.