Welcome to End Point’s blog

Ongoing observations by End Point people

My Favorite Git Commands

Git is a tool that all of us End Pointers use frequently. I was recently reviewing history on a server that I work on frequently, and I took note of the various git commands I use. I put together a list of the top git commands (and/or techniques) that I use with a brief explanation.

git commit -m "****"
This is a no-brainer – as it commits a set of changes to the repository. I always use the -m to set the git commit message instead of using an editor to do so. Edit: Jon recommends that new users not use -m, and that more advanced users use this sparingly, for good reasons described in the comments!

git checkout -b branchname
This is the first step to setting up a local branch. I use this one often as I set up local branches to separate changes for the various tasks I work on. This command creates and moves you to the new branch. Of course, if your branch already exists, git checkout branchname will check out the changes for that local branch that already exists.

git push origin branchname
After I've done a bit of work on my branch, I push it to the origin to a) back it up in another location (if applicable) and b) provide the ability for others to reference the branch.

git rebase origin/master
This one is very important to me, and our blog has featured a couple of articles about it (#1 and #2). A rebase rewinds your current changes (on your local branch), applies the changes from origin/master (or whatever branch you are rebasing against), and then reapplies your changes one by one. If there are any conflicts along the way, you are asked to resolve the conflicts, skip the commit, or abort the rebase. Using a rebase allows you to avoid those pesky merge commits which are not explicit in what changes they include and helps you keep a cleaner git history.

git push -f origin branchname
I use this one sparingly, and only if I'm the only one that's working on branchname. This comes up when you've rebased one of your local branches resulting in an altered history of branchname. When you attempt to push it to origin, you may see a message that origin/branchname has X commits different from your local branch. This command will forcefully push your branch to origin and overwrite its history.

git merge --squash branchname
After you've done a bit of work on branchname and you are ready to merge it into the master branch, you can use the --squash argument to squash/smush/combine all of your commits into one clump of changes. This command does not perform the commit itself, therefore it must be followed by a) review of the changes and b) git commit.

git branch -D branchname
If you are done with all of your work on branchname and it has been merged into master, you can delete it with this command! Edit: Phunk tells me that there is a difference between -D and -d, as with the latter option, git will refuse to delete a branch with unmerged changes, so -d is a safer option.

git push origin :branchname
Want to delete branchname from the origin? Run this command. You can leave branchname on the origin repository if you want, but I like to keep things clean with this command.

git checkout -t origin/someone_elses_branch
Use this command to set up a local branch to track another developers branch. As the acting technical project manager for one of my clients, I use this command to track Kamil's branch, in combination with the next command (cherry-pick), to get his work cleanly merged into master.

git cherry-pick hashhashhash
Git cherry-pick applies changes from a single commit (identified by hash) to your current working branch. As noted above, I typically use this after I've set up a local tracking branch from another developer to cherry-pick his or her commits onto the master branch in preparation for a deploy.

git stash, git stash apply
I only learned about git stash in the last year, however, it's become a go-to tool of mine. If I have some working changes that I don't want to commit, but a client asks me to commit another quick change, I will often stash the current changes (save them but not commit them), run a rebase to get my branch up to date, then push out the commit, then run git stash apply to restore my uncommitted changes.

Admittedly, several of my coworkers are git experts and have many more git tools in their toolboxes – I should ask one of them to follow-up on this article with additional advanced git commands I should be using! Also take note that for us End Pointers, DevCamps may influence our git toolbox because it allows us to have multiple instances (and copies of the production database) running at a time, which may require less management of git branches.


Brian Gadoury said...

I'm a big fan of this little fella for amending unpushed local commits when I've made a small typo or omission:

# commit your changes
# realize you need to make a small tweak to that commit
git commit my_tweaked_file.rb --amend -C HEAD

That will amend the last commit with by committing any new changes to my_tweaked_file.rb and automatically re-using the same commit message without opening an editor, etc.

Steph Skardal said...

Thanks Phunk! You are the coolest.

Jon Jensen said...

Phunk, yes, very helpful. That means you're reviewing your commit before pushing which is a good thing! :)

BTW you can leave off -C HEAD since that's the default.

Jon Jensen said...

Steph, you wrote: "I always use the -m to set the git commit message instead of using an editor to do so."

I discourage that habit especially among new users. There are many good things about using an editor to make a commit message: You see the `git status` output in comments so you can consider one last time whether you're committing everything you want, and nothing extra.

You also tend to be more thoughtful in your commit message, where needed going beyond a one-liner to explain the reason for the change, reference a ticket # or URL, etc.

-m is a useful option, but I don't think it should be used sparingly by more advanced users.

Steph Skardal said...

Thanks, Jon! That's very good justification against using the -m argument. I've edited the article to reflect your comment.

Brian Gadoury said...

Jon: -C HEAD skips the "open the editor" step. That's the sugar on top right there. :)

Jon Jensen said...

Phunk, oh, I see. Well, then I oppose that for the same reason I oppose the indiscriminate use of -m. Having the editor open shows important information about what you're about to do.

I bet you like to run with scissors too!

Brian Gadoury said...

While I understand your concern, I'm heavy on the `git status` and `git diff` when I'm working, so I brave the peril of -C HEAD. :)