I spent a lot of time last weekend going through screencasts. The Code School videos have really great production quality, but my mind is better tuned for the kind of asynchronous learning you can only get from reading.
So, my rule of thumb is to follow along with these screencasts while recording notes. The following is a dump of my notes about Git. Already a few of these tricks have come in handy.
Note: If you’re serious about learning Git, I recommend Git from the Bottom Up (PDF). I read that a few months ago, and while it didn’t make a whole lot of sense then, I realize now that it has coloured my thoughts in a certain way when I’m actually using Git.
Fixing the last commit
git commit --amend -m "New message"
Once in a while, you’ll commit something, and then realize “that’s not what I wanted”. As a Git novice you might just create another commit with a message like “oops”.
Rather than polluting your history, you can use –amend. On the surface (forgive me if my language is imprecise), this reverses the previous commit, and replaces it with what you have now.
Caveat: If you already pushed to a remote like Github, you will have to do
git push --force, since Git will think you have changes to pull. Be careful with these more dangerous commands; always take a backup.
Soft and hard resets
Resets are all about changing history. Some people believe this goes against the principles of source control, but what else are you going to do if you’ve published sensitive information?
If you know about the Git internals, you’ll know all about the HEAD pointer and what it does behind the scenes. Chances are if you’re considering using the
reset command you already know all of this. I think resets are best demonstrated by example. Consider the following scenario:
Consider the following scenario:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Fixing it with a soft reset
1 2 3 4 5 6 7 8
Fixing it with a hard reset
1 2 3 4 5 6
Fixing it with an amend commit
1 2 3
Create a branch:
git branch feature
Switch to a branch:
git checkout feature
Create a branch and switch to it in one step:
git checkout -b another-feature
Merge an experimental branch into master
1 2 3 4 5 6
Pushing and pulling
Developer B, meanwhile:
1 2 3
1 2 3 4 5 6 7 8 9 10
Editing the same file - merge conflicts
When DevA and DevB both edit the same file in isolation, the first person who pushed “wins”.
The second person now has some work to do. Git will dump a bunch of garbage into his file, showing Dev A’s changes vs Dev B’s changes. He has to resolve this manually (by editing the crap out of the file, and picking out who wins.)
When he commits, the default message will be “Merge branch ‘master’ of ….”
So far, I’ve only ever seen local branches. For the most part, only the
master branch ever makes it up to Github. The “branch-work-work-merge-push” pattern. But what if you have a highly experimental branch, which might take a few weeks to work on, while mainline development continues in parallel? You might still want to push those experimental changes up to Github.
For this we need a remote tracking branch.
Now, when another dev pulls, they’ll see the new branch is now available, but not locally.
1 2 3 4
1 2 3 4 5 6 7
Listing remote branches, whether they’re tracked or not
git remote show origin
Deleting a remote branch
This stood out as a huge red flag to me. This is not at all intuitive, obvious, consistent, or sensical. But, to delete the remote branch on Github, we do:
git push origin :secret-sauce
This begins to make sense later, when we see how to push a local branch to a different remote branch.
Deleting a local branch
What if someone else already deleted my remote branch?
1 2 3 4 5 6 7 8 9
Pushing a local branch to a different remote branch
What if you want to push from local branch “secret-sauce” to remote branch “master” (e.g. for Heroku, since it only lets you push to master).
That was as far as I got. There’s still tagging, rebasing, and a few other things to cover at a later date. For now, I have just enough Git knowledge to be dangerous.
n.b. Sorry about the brain-dump format of this post. Kudos for making it this far.