#GIT-ING IT
This is a short guide to start you off with Git. It's a bit of a learning curve to use it effectively, but like all good tools, Git will pay you back in spades once you understand even the basic commands.
#####First, a few concepts to familiarize you. Reading these through 3-5 times would not be a bad idea.
- A file is a String on your harddrive. Git's purpose is to help you track, understand, and manage the history of these strings, and ease the difficulty of multiple people working on the same codebases.
- Git is primarily concerned with lines of code, and not files...it tends to handle files badly (not seeing empty directories, not recognizing file deletions).
- A commit is a group of changes to your source code with a description, it's like saving your work on your local machine.
- A repository what stores all the commits for your project.
- A branch is a commit with a name, it's like copying your work to another directory so that you can conveniently get back there.
- Your working directory is the local file system, it's just the bit of your repo that you can currently see.
- Your staging directory is a "commit-in-progress", when you
git add somefile.ext
,you are moving a file from your working directory into the staging directory, when you like the set of changes in the staging directory, you turn them into a
commit.
##Things that will save you heartache...and headaches
- EVERY TIME YOU DO ANYTHING IN GIT, THE NEXT COMMAND IS ALWAYS
git status
, TO MAKE SURE IT DID WHAT YOU THINK IT DID - There's no need to copy your whole directory as a backup, you can just commit and then later tell git you want to see what it looked like at this commit.
- Git doesn't know about changes unless you commit them, so...NEVER PULL WITH UNCOMMITTED CHANGES!
- Never, Never, Never, add personal information or passwords/keys of any kind to a file you will push up to Github, unless you are SURE it is in your Git ignore, or you are using a gem like Figaro, and using it correctly. Once it's up there, it's up there for good, and the only thing to do is change passwords/generate new keys.
- The messages printed when you do
git status
will tell you how to move code between them (ie remove the changes, or unstage them)
#Commands:
-
git branch
- Displays branches you have in the current directory. The branch you are on will be highlighted/emphasized
-
git checkout mybranch
- Switches you to whatever branch you put in the place of mybranch (mybranch is just a placeholder name)
-
git checkout -b newbranch
- Creates a new branch named whatever you put in place of newbranch, which is just a placeholder name
-
git branch -d branchidontwantanymore (you can also use -D instead of -d)
- Deletes the branch you put in place of branchidontwantanymore
- Note that -D is like "for real, delete it", whereas -d is a safer alternative (it will only delete it if it's been merged into some other branch)
-
git merge branchiwanttomergefrom
- To use git merge, switch to the branch you want to merge stuff TO, then use git merge and name the branch you want to pull new fun additions FROM.
- example: I just pulled down from the master on Github and want to merge my LOCAL master with my branch, awesome_branch. I would first checkout to awesome_branch, then from the command line, I would type git merge master, which would add all of the changes I pulled down to my local master to my local awesome_branch branch.
-
git pull origin master
-
Merges the Github master repository with the branch you are currently on.(make sure you are on master unless you have good reason not to be). Note that this is actually a conjunction of 2 steps: fetching (get that remote branch and make it available locally) and merging.
-
"origin" refers to the original repo you cloned down from(if you forked and then cloned, it refers you YOUR repo), and "master" refers to the branch of that repo. If you created the project from scratch and used git init, origin is your original repo.
-
You can just use git pull if you are always branching off of a normal repo during your project, but using origin master won't hurt.
-
-
git push
- This alone may not do what you want it to do...I use:
-
git push origin branchiampushingfrom
- branchiampushingfrom is usually NOT master, as it's best practice to push up to a branch and then merge to master
after comparing changes on Github. If you are working on a solo project, do as you like. When in a group, YOLO is
always a nono.
Yet another way to do it is git
push origin *branchiampushingfrom:branchimpushingto*
- Just stick to the first way until you find you need to use this one.
- branchiampushingfrom is usually NOT master, as it's best practice to push up to a branch and then merge to master
after comparing changes on Github. If you are working on a solo project, do as you like. When in a group, YOLO is
always a nono.
Yet another way to do it is git
#Good work flow:
##Setup:
1. Person A forks and clones or creates the project.
2. Everyone else clones down from person A's repo.
##Doing work:
1. Everyone, including person A, checks out to a new branch named after the work they are doing using
git checkout -b *mybranchname*.
2. Do some work....
3. When a branch is ready to be pushed up to master, the branch owner checks the following:
-local master is up to date with Git master, and local branch is up to date with local master
- (unless you are sure, to be safe always just switch to master, git pull origin master, switch to your branch,
and git merge master.)
-all tests are green
-bundle has been done and all gems are updated - bundle
-migrations are current(if using a DB) - rake db:migrate
4. Push your branch up to a branch on the origin repo with - git push origin *yourbranchname*.
5. Go to Github and open a pull request for the branch you just pushed up. Tell your peeps to check it out.
5. Someone else checks the files changed, and either approves or rejects.
- if rejected, fix issues and re-push the branch. Github will update it automatically.
- if approved and merged, EVERYONE should:
- pull down from Github master to their local master
- merge local master to the branch they are working on.
- bundle
- if working with a DB, rake db:migrate to make sure migrations are current(be careful if you are also working
on migrations at the same time)
- run tests to make sure nothing exploded.
NOTE: If there are multiple people who have pull requests open, they should be merged one at a time, fixing merge conflicts as they arise.
6. Once your branch is merged, you can use git pull origin master to make sure things are in sync.
7. Delete your old branch with git branch -D *branchtobedeleted*.
8. Create a new branch with git checkout -b *newbranchname*.
####A few more nuggets of wisdom (courtesy of Josh Cheek who sprinkled awesomeness throughout this guide)
- A git repository is immutable. You make changes by adding to it.
- If you want to delete a line, you add a change that says "and remove this line".
- This way, you can build the current state by looking at the sum of the previous commits, and you can always get back to an old state (like when things worked :P)
- Your commits are stored in a directory in the current folder named .git. You don't normally see it because files
that begin with dots are considered hidden, and won't be shown unless you explicitly ask to see them with
ls -a
- The files in your directory are transient and irrelevant, when you do things like switching branches, git will replace them with whatever the file looked like at the time of the commit. This means it's irrelevant to delete a file on the file system, you must delete it from git.
- HEAD always refers to the current commit.
git stash
is purgatory for code, usually it's where code goes to die.
- Some commands retain state between invocations, a merge with a conflict, for example.
- You can usually get out of this with the same command and the
--abort
flag (iegit merge --abort
).
- You can usually get out of this with the same command and the