Loading, please wait...

picture of me
Joe Rushton Fullstack Web Developer

Git Bits That You Must Learn As A GUI User

09th February 2019 Reading Time: 10 mins
Tags: GIT Version Control

If you find yourself leaning quite heavily on a GUI to handle your day-to-day git, then theres a good chance that when faced with a terminal and git respository, you reach for google and stack overflow for every damn command. Everything from how the hell do I list local and remote branches to, I need to merge in my changes but there's no pretty merge button for me to press.

 

There are a tonne of cheat sheets out there which are definitely handy for a quick reminder, however sometimes it's hard to know which command to reach for when presented with a never-ending list of commands you barely understand. This post will explore all of the operations you'd need to know to abandon your GUIs completely - with some bonus stuff to give you a reason to hit up the terminal.

 

Firstly, git status is going to be your bread and butter. You'll run it before and after you touch anything on the command line, so get it ingrained into your muscle memory.

 

Commiting and Pushing

Stage all of your changes: git add .

Commit your changes locally: git commit -m "your commit message"

Push to the remote branch: git push

 

Since the above three operations are so common for development, it might be worth setting up a simple bash alias

gitpush() {
    git add .
    git commit -m "$*"
    git push
}

alias gp=gitpush

The usage would be gp "your commit message"

 

git push assumes you already have your local branch hooked up to a remote branch. If that's not the case, git push -u origin branch_name will sync up your current working branch to remote branch_name or create it remotely if it doesn't already exist.

 

Pro Tip: Interactive Staging

You can use interactive mode when staging your changes, which allows you to view your changes one-by-one and confirm if you want to include them as part of your next commit. This forces you to review your code and potentially catch bugs early on in the process. To begin interactive staging: git add -p

 

You will be presented with a 'hunk' which is essentially a line of code (or group of lines) that have been modified, from which you can choose to stage or skip. Once you've decided, you'll be presented with the next hunk and so on. You'll probably only use the y/n/a/d options, but here's the full list:

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

If you want to start over, you can unstage all of your changes with git reset HEAD. This won't delete any of your changes.

 

What about viewing commits?

git log --all --decorate --oneline --graph

I appreciate that's a bit of a mouthful and git log alone will do the trick, but the flags make it more tolerable to view the history. Just remember the acronym "A Dog" or stick it into an alias.

 

If you want to view all of the information for a specific commit (the changes, author, commit message, date etc) you can use git show commit_hash

 

Branching 101

git branch will list all of your local branches

git branch -a will list both your local and remote branches

git checkout -b branch_name will create branch_name locally as well as switch over your working branch

 

You've made a ballsup with the branch name, git branch -m old_branch_name new_branch_name will sort you out. If you leave out the second branch name, it'll use the first name as the new name for your current working branch. You can use git status if you're not sure what branch you're on.

 

You've made a ballsup with the branch name but you've already pushed it up to the remote. That's not a problem:

# First, rename your local branch as described above

# Then delete the old branch from the remote, and push up your new branch:
git push origin :old_branch_name new_branch_name

# Finally link up your local branch with the new remote branch
git push origin -u new_branch_name

An aside note on the above, the colon (:) used in the push command takes the following signature.. source_branch:destination_branch and since we don't specify a source :old_branch_name, it pushes nothing up which is shorthand for saying delete the remote branch.

 

Deleting a branch locally is as easy-as git branch -d branch_name use a capital D instead of lowercase as a sort-of force delete, as it tells git to delete irregardless of it's merge status.

 

We've already spoken about deleting a branch remotely with the shorthand : syntax, but here's perhaps a more declarative version: git push origin --delete branch_name

 

Merging Basics

Merging master into your feature branch:

git checkout feature-branch
git merge master

Merging master into feature-branch regardless of your current working branch:

git merge master feature-branch

By default git will try to fast-forward if it can. A fast-forward is when, instead of constructing a merge commit, git just moves your branch pointer to point at the incoming commit. The opposite would be to create a new, separate commit that states "Merge master into feature-branch" which can be forced by passing the --no-ff flag to your merge command.

 

If you've tried to merge in a branch but there are conflicts, then you'll have to deal with those manually (I'm assuming you know how to handle merges). You can cancel the merge with git merge --abort

 

If you've merged in a branch locally but decide to back-track, you can reset your local branch back to the state before the merge: git reset --merge ORIG_HEAD

 

Another alternative for the sake of completion would be to find the pre-merge commit hash (you can use git reflog and look at the second row down which should in theory be the commit before the merge) and run git reset --hard commit_hash

 

Viewing Differences

git diff branch_name will show you the differences between your working branch and branch_name.

 

git diff commit_hash will show you the differences between your working branch and a specified commit.

 

git diff commit_hash~ commit_hash where commit_hash is the same in both instances, will show the differences between that commit and it's ancestor (aka, where it branched off).

 

Replacing one branch with another

We're getting a bit more into edge-case territory, but these are all things that I've had to do in the past. If you need to swap out the master branch entirely for a completely different branch, you could take this simple approach of renaming and replacing:

git branch -m master old-master
git branch -m new-master master
git push -f origin master

 

Changing a commit message

Enter rebase. Rebasing is a command that allows you to modify the history of a git repository in any way that you like. To change a commit message, you can start the interactive rebase with git rebase -i and then find the commit you want to rename and change the work "pick" to "reword" or "r" for short.

 

If you don't see any commits when you start the rebase (it'll show the word 'noop' in that case), this means you've already pushed and at that point you want to be careful when it comes to modifying the history because it can cause conflicts if someone else is working on the same remote branch. To get around this, you can use git rebase -i HEAD~2 which will show the latest 2 commits from the remote branch. You can of course change the number to anything you like, or use git rebase -i --root to take action on every single commit since the start of time.

 

If in doubt about a rebase, you can abandon ship with git rebase --abort

Back to Homepage

Find me on social media