Git tips and tricks

A few nice tips and tricks for how to make work­ing with Git more effi­cient.

Forking, remotes and pull-requests

This might be just me, but I don’t con­tribute that much to open source, by far not as much as I real­ly ought to. This leads to me every time I do end up con­tribut­ing need­ing to remem­ber how I update my fork from the orig­i­nal one.

In the end of the day, it is actu­al­ly fair­ly easy. Git allows for sev­er­al remotes, IE sources to fetch changes from and/or (if you have the right per­mis­sions) to push to. The stan­dard one, your local fork, is most often known as origin, though you can change the ori­gin if nec­es­sary (I think that’s a touch out of scope for this set of tips & tricks, how­ev­er). So, with­out fur­ther ado, this is how you inter­act with the so-called upstream (that name isn’t set in stone, but it’s fair­ly well-known).

# You can add more remotes by name and url
git remote add upstream git@github.com:<original author>/<repository name>.git

# Fetch changes from upstream, using fetch rather than pull to not merge in changes immediately
git fetch upstream

# Now that you’ve established that you want to merge in the changes
git merge upstream/master

Now you can do all the changes you want in your own local repos­i­to­ry, push them to your github repos­i­to­ry, and cre­ate a new pull request to the upstream repos­i­to­ry.

.gitignore and the big “whoops!”

I’ve been there (sev­er­al times) and I’m not ful­ly cer­tain I believe you if you claim you haven’t. You for­got to ini­ti­ate a .gitignore file before your first com­mit, or you changed your mind on where some­thing that should be ignored was stored, or you missed some­thing in the pat­tern lead­ing to your entire set of bow­er-com­po­nents end­ing up being part of your repos­i­to­ry. Did I men­tion whoops!?

Warn­ing, fol­low­ing these instruc­tions may lead to the loss of the files you are want­i­ng to ignore, so keep a back­up of them, or in some oth­er way ensure that you will get them back!

Before you do any­thing, make sure you com­mit your changes, or they are like­ly to get lost too. You have been prop­er­ly warned, so let’s see what needs to/can be done. Also, make sure you have fixed and com­mit­ed your prop­er .gitignore file before start­ing, or it’s going to be a tad incon­ve­nient.

git rm -r --cached . # This recursively removes everything from the commits
git add --all # adds/deletes files
git commit -m "Working .gitignore" # commits, using the given message

And if you didn’t know, you can replace . with a par­tic­u­lar file, or a file pat­tern.

Git hooks

There are sev­er­al places in the git work­flow that you can attach shell scripts, so-called hooks. The full list can be found in .git/hooks, where each avail­able hook has a sam­ple script named by the hook and the exten­sion .sample. Sim­ply remove the exten­sion and the hook will be active.

If you cre­ate your own script, you need to make sure it’s a valid shellscript, and that it has per­mis­sion to be exe­cut­ed. I’ve been tripped up by it chang­ing the line end­ings on me, so if there’s issues, dos2unix is always very help­ful.

The only hook I real­ly use at the moment is pre-commit, which runs right before the com­mit is final­ized, mean­ing that if it fails, the com­mit will not go through. The one I use the most uses grunt commit, which runs the lint­ing and test­ing tasks, and the script also uses parts of the default script:

[gist id=6724878]

I intend to gath­er a few more of the hooks, once I under­stand what exact­ly they do, and how to fit them into my work­flow the best.


For the moment comments are not enabled, but feel free to reach out on Twitter.