My Git Cookbook
2017-09-20I cook a lot (real cooking). However I find myself not sampling from my full pool of available recipes - only those I tried recently are considered. Good recipes will eventually lost to time. To manually set up a recipe pool with larger capacity, recipes are documented into cookbooks.
The cookbook is subject to continuous amendment as me the Stats person is marching through the foreign land of software develepment.
A long, long time ago, in a land far, far away, there was a Stats person...... Anyways, let's save the tale at another time.
Basics
The simplest workflow
1-2-3-4's are the best for lazy peeps, but they are also more prone to misunderstanding. So warning: Only read on if you know what each is about.
git clone
some repo to a local place.- (optional, but recommended)
git checkout -b
. - Make changes.
git add -u
to add changes made to pre-existing files. Thengit add
.git commit -m
.git push -u origin
.
And, voila, your changes are under the sunlight.
Set up SSH for Github
You want to do this because you want SSH without entering your password everytime.
ssh-keygen -b
You will find a `id_rsa.pub` in `.ssh` file in your home directory. Will ya just copy the content to github on "Settings - SSH and GPG keys - New SSH key"?
Share Your Shell Without Sharing Your Password
Story: The professor decided (very kindly) to let students use his research desktop for the computational complex homework. The TA came in and ask students to run some weird scripts and send a `id_rsa.pub` to him by email so that they could access the desktop. Here is how he do it.
Simply add the content of id_rsa.pub
to ~/.ssh/authorized_keys
.
Download a git repo
Git personnel say clone when they mean download to enhance their geekiness.
git clone
Please note that this will be only your copy of the original repo. You are free to mess with it, but the repo up there online will not change unless you tell git to do so.
Story: A colleague asks another, "my git clone is not working at all, please help." The other colleague tried in command line found nothing wrong with the repo. "What are you doing exactly?" "I clicked on clone..." "So you are using S*****Tree? Try restarting." Lessons learned. Command line champs.
Take a look at your git tree
Think of git as tree: you have a trunk (master branch), and branches coming out of the trunk at some point. Git people generally want to make changes to their codes on a branch of the tree, and merge them back to master. This avoids the ugly story of you find your changes being buggy and cannot return to the glorious past.
So, what are the branches in this repo?
git branch -a
Green is the branch you are in; reds are the branches in the repo online but not in your local repo; whites are branches in your local repo.
You can go to white branches by
git checkout
You can create a local branch tracking some branches in the online repo
git branch
Add your changes to the stage
Now you have done your job as a dev. You are eager to put them under the limelight. Git people called this staging.
git add
Want to add all changes at once? This only applies to the case where the files you changed exist previously in the repo.
If you added new files to the repo, you need to git add
.
git add -u
You are also able to remove files on the stage:
git rm
git status
git reset
Commit your changes when you are done with everthing
You are still not committed changes to your repo. By committing, you will be leaving a mark on this branch's history. People will be able to see what did you do in your commit. It is like a milestone for your dev efforts. To commit
git commit -m
Don't make too many commits for some small feature in your code. This will make your repo history looks messy. Already have too much commits? No worries, take a look at the interactive rebase section below.
There are many good docs on how to write a good commit message. Ok tl;dr people, your message should at least be concise and clear catching the main changes in the commit.
A good practice is to add a small paragraph to your commit message. You can either create a file with the first line being your message and the third line your paragraph, and use
git commit -F
Or, you can simply press enter while not closing your quotation marks with -m
.
Push your local changes to origin
Now you have several commits ready that you want to push to your online repo. To do this,
git push -u origin
By adding -u
, you are telling git that this remote branch is the mirror of your
local branch. When you git pull
(see later), your local branch will be pulling from
this remote branch.
Download changes in the online repo
When your branch is outdated, generally you want a
git pull
to sync up. It is equivalent to git fetch
and then git merge
, the former
will add in what happened at the online repo while you are doing your work, but leaving your work
untouched, the latter will merge the two lines of development. When nothing happens in your local
branch but there is a lot happened online, do a git pull
, otherwise do it separately.
Resolve conflicts
When you want to merge two branches both originating from some common ancestor, do a
git merge
while you are in another. However sometimes the branches each will have a word on the same part of the code. When git can't decide who to listen to, it gives you
Try to see it my way, do I have to keep on talking till I can't go on? While you see it your way, run the risk of knowing that our love may soon be gone.
in the conflicting file. Simply delete these extra marks and leaving the file the way you want it to be when you save and exit.
Rebasing
Rebase in its simplest terms means moving your branch to a new place such that it looks like you started to work from elsewhere. There are many good tutorials available online. To rebase your working branch to master, for example, with your working branch, do
git rebase master
If this branch is tracking some remote branch, you will have to delete the reference before pushing your
rebase to the origin (git push -d
).
Other simple operations
Rename a branch
Simply git branch -m
.
Delete a branch
- Locally:
git branch -d
- Remotely:
git push -d
Advanced
Now you are in the advanced land. People will assume you are a responsible adult being able to suck it up when you lose it. Well, not yet? Make a copy of your local git repo before you take adventures.
Interactive rebasing
This is really the number one tool a git user should know after knowing all the basics. It feels
like the git analog of awk
or sed
of bash. Examples of its usages:
- Combine several commits into one.
- Change a previous commit's message.
- Change a previous commit's content.
- Retroactively check which commits fail a certain task.
I usually prefer to use
git rebase -i
to invoke interactive rebasing. I feel it is the most intuitive among other choices.
is the first few (until unique) digits
of the hex key of the commit. After command you will see a text document pops out listing
the commits since the one you want to retain. It is quite self-explanatory. Just read
the comment section for more information.
After you are done, save it and close it. Git will process your request from the very top line. If stopped instructions will be given. Nothing differs far from basic git commands.
exec
is a little bit confusing. This one needs you to insert lines between the commits.
For example, I can insert `x date` between commits and in the process of rebasing git will tell me
the time when it reaches that point.
Fixing a pushed change
First of all this is unrecommended unless you know what you are doing exactly. By design users are not supposed change contents that they have already pushed to the repository. However exceptions do exist. If you think you are in one of these exceptions, read on.
It's simple, if you already have a local branch tracking the remote branch which contains commits
you want to change, then rebase squash
or fixup
locally and commit. If not, you will need to
either force push by git push -f
or delete the branch
git push -d
and add again git push -u
.
In either case do make sure no one else is working on the branch.