Git is used for version control, and also for holding all our files.
- It provides options to
clone
repositories (download them from online) - The repository is broken up into
branches
, a list ofcommits
outlining the history - The typical workflow:
- clone the repo
- make sure you're on the master branch
- make a new
local
branch (on your pc) - make changes, add files, etc.
- commit those changes local
- push those changes to
remote
branch (online) - get approval and merge those changes into the remote master branch
Use this to get a new ssh key
Use this to add it to your git account:
This will authenticate your machine. Use the ssh
version of git to git clone
, not the https
Cloning repos
- you can
clone
(download from online) a repo usinggit clone <repo to clone>
- for example,
git clone git@github.com:raejeong/dextre.git
- for example,
- newly cloned repos end up on the default branch, often
master
ordevel
Changing branches
- you can change to a different branch with
git checkout <branch name>
- if you specify the
-b
flag, it'll create a new branch with that name instead- The new branch will be equal to the branch you were just on (have the same
commits
) - This only creates a local branch, to create an equivalent remote branch:
git push --set-upstream origin <branch name>
- execute that while you have the branch of interest checked out
- The new branch will be equal to the branch you were just on (have the same
Once you have a branch, you can start making changes.
When you're happy with the changes, you can add
, commit
and push
them
-
Use
git status
to see the state of your current directory- It'll usually have some files in
red
which you've made changes to - you can use
git diff
to see all the changes you've made - you can also use
gitk
orgit gui
for an interactive approach
- It'll usually have some files in
-
Once you're happy with the changes, get them ready for committing with:
git add .
(thisstages
all files that have been changed)- if you want to be selective,
git add <path/to/file/filename.fileextension>
- You can add as many as you want one by one, or use
*
to add folders
- You can add as many as you want one by one, or use
-
Once all files of interest are added, commit them:
git commit -m "<enter a useful message describing changes>"
- you can use
gitk
to see the new commit - you can also use
git log
to see the new commit- enter
q
to quitgit log
- enter
-
if you make an accidental commit, you can revert it
- open up
gitk
and right click on the prev commit - select
reset branch to here
, and then you have a couple of optionshard
will reset the branch to that commit and delete everything above itsoft
wil reset the branch to that commit, but keep the reset asunstaged
changes
- open up
Once you're happy with your commit, push it to remote:
git push
- if it says there is no remote, create it with
git push --set-upstream origin <branch name>
- if it says there is no remote, create it with
- This won't work if someone else has made changes to your branch (or you did from a diff computer)
- In this case, you'll first have to
git pull
the changes- This does a messy merge, so instead, use
gitk
to do asoft
revert on your commit, pull and recommit
- This does a messy merge, so instead, use
- If you're confident the changes to remote are useless, you can force push
git push -f
- This will overwrite the commit history on remote and replace it exactly with what you have locally
- This is useful if you just
rebased
your branch and know that your local is more correct than remote
- In this case, you'll first have to
Once your branch works, you can make a pull request
(PR
) to merge your changes to master
branch
- This is all done online with the git website
- Before you do this, make sure you
rebase
Rebasing replays your commits onto a new base
commit, hence rebase.
In otherwords, while developing
- you started with a new branch based of master, which started on some commit (it's base)
- you then made a number of commits, say 4, on top of that base
- while you were doing that,
master
has progressed and has new commits - before merging, we need to move all your commits to the new base (
rebase
), the latest commit on master
To do this, first git checkout master
and git pull
to make sure you have the latest master
- go back to your branch with
git checkout <branch name>
- run
git rebase origin/master
- This will add all your commits on top of
master
one by one
- This will add all your commits on top of
- If you have conflicts, use your favourite editor to resolve them
ctrl+shift+F
for<<<<
to find them allgit add .
any changes you makegit rebase --continue
to keep going
- If you make a catastrophic mistake,
git rebase --abort
will undo yourrebase
attempt
Once all the conflicts are handled, we're done, let's push it to master
git push
won't work, by rebasing we changed the commit history- use
git push -f
instead
When merging the PR, select the Squash and Merge
option
- This squashes all your commits into a single one, and puts it on top of master
- This way, master will have a single, linear history and it's easier to revert PR's if something goes wrong
Sometimes you make a bunch of commits that don't need to be distinct or are too granular If you have to rebase, you have to deal with conflicts on all of those commits one by one, which is a pain. You might've also made a change, commited, reverted the change, commited again, which is a pain to rebase through too
To solve this, you can squash commits
- go to your branch
- run
git log
to see all your commits, find the commit hash that's one before all the commits of interest and copy it - run
git rebase -i <commit hash>
- This pulls up an interactive terminal that list all your commits since that hash
- all the commits say push, but if you change some of them to
s
orsquash
, it'll squash it with the commit above Ctrl+X
when youre happy, edit any commit msg you like, answer the prompts and you're done
git log
orgitk
to see your new commit history- if you'd pushed to remote before, you'll likely need to
git push -f
now
Sometimes you have multiple tickets you're working on at once, say A
and B
.
B
requires all the things that A
is implementing, so you base your branch B
on top of A
(instead of master).
When you make the PR, you can set the base branch to A
as well, so people can focus on the relevant files
After A
has been merged in, change the base back to master, and you'll have a bit of a mess (duplicate commits from A
)
Even worse, if A
continued development, it may have diverged from when B
was branched off
The fix is simple
git checkout master
andgit pull
to make sure you have the latest stuff (afterA
has been merged)git checkout B
andgit log
(orgitk
)- Find the commit where
B
actually starts note the description git rebase master
(you'll get a whole bunch of conflicts)git rebase --skip
every commit that is not part ofB
and your mess will be ignored!
Sometimes you execute a command and realize you fucked up. Git let's you turn back time!
git reflog
shows you all the commands you executed recently- All of those
states
have commit hashes, so you cangit checkout <commit hash>
to jump to that point in time! - Once you're there, you can
git checkout -b <branch name>
and then you'll have a nice reference to it - From here, you can also manually copy paste stuff out of the
git
repo, etc.
Sometimes you accidentally change files you didn't want to touch. Just revert them to the base branch of choice
git checkout origin/<base branch> -- <path/to/file/filename>
- You can use
*
to get multiple files or folders - you can also
git checkout origin/<current branch> -- <path/to/file/filename>
to just revert to what's on remote of current branch - This is also useful for quickly grabbing a file from a different branch for testing
Alternatively, maybe you just want to scrap what you have and revert to a stable version on remote
git reset origin/<branch name> --hard
will destroy local changes and revert your current branch to remote version of current branch- use
--soft
to revert but keep the changes asunstaged
- use
Sometimes you're in the middle of some work, but need to do something else. With unstaged changes, you can't switch branches, and you don't want to commit because it's unstable
git stash
will stash all your changes- You can then switch branches, do whatever you want as
- Once you're done and ready to return,
git stash apply
will bring back the latest thing youstashed
- You can
git stash list
to see everything you've stashed that's available - You can also
git stash apply --index <number>
to apply older stashed items instead of latest
- You can
Your local repo doesn't update automatically, you have to update it and sync with remote
git fetch --all
will grab all the new things that have happened since you last made that call
Sometimes there's a single commit somewhere that you want to add to your current branch. Use git cherry-pick
git cherry-pick <commit hash>
will apply that commit on top of your current history- if there are conflicts, resolve them, save and
git add .
andgit cherry-pick --continue
- if things go horribly wrong,
git cherry-pick --abort
- if there are conflicts, resolve them, save and
- You can use the
-n
flag to just stage the changes (ready for commit) instead of actually apply the commit- Will still resolve the conflicts as usual, but will also have to
git commit -m "<commit message>"
afterwards - Useful if you just want the changes but don't plan on keeping them
- Will still resolve the conflicts as usual, but will also have to