
Hello friends!
This time we'll be talking about some various ways that we can use to do common tasks with Git on the terminal.
We'll understand more about Git functionality and also add some new tricks to our toolbox when using it to manage changes in our local workspace and in GitHub (or GitLab, Bitbucket, etc.)
So if you are ready to get started, let's dive right into it!
The basics
For most of us, we are already familiar with the common workflow of git which is something like...
Pull latest changes from remote repo, work on the code, add our changes, commit them and push them to the remote repo
Since normally the bulk of the work doesn't happen in the master branch, we use feature branches which can be created with the command
git branch {branchName}
and then we can move to the recently created branch, or we could use everyone's favorite shortcut
git checkout -b {branchName}
Using branches it's when Git becomes more interesting. The branches can exist both in the remote repo and also in our local copy of it
Normally, we create the branches locally and then push them to the remote repo although we can also create them the other way (i.e. from the remote and them pull them locally.)
Now, how do we know what branches exist and whether or not they have a matching remote branch?
First let's make sure that weactually have a remote repo linked to our local one. We can check that with thegit remote
command.
Although it's more useful when we use the--verbose
flag or-v
for short like so
git remote -v
Once we know we have a remote repo, we can see the existing branches on our local withgit branch
which will list all branches created.
We can get more info about them with the-v
flag that will show us the id and name of the last commit made on that branch.
And we can geteven more info on the branches with the-vv
flag that will show us not only the info of the last commit but also the name of the remote branch the local one is pointing to (if it has one.)
Taking things up a notch
Now, we know how to create branches and move to them once created.
In order to navigate between different branches we would have to use thegit checkout
command and the name of the branch.
Though there's a nifty little trick to navigate back and forth between two branches without having to write their names every time. To do so, use the command
git checkout -
Once we make changes to a file, we can save it to theworking directory, add it to thestaging area and then make a commit before pushing it up to the remote.
There are several things we can do once we have changes committed to the Git history (like being able to recover changes if something unwanted happens for instance)
The standard command for that isgit commit
which if used alone will open the Git default editor so that we can introduce a commit message.
You can also tell Git which editor you want it to use as a default by running the command
git config --global core.editor "your_editor_of_choice"
In my case I use Vim (the grandfather of all text editors) but you can use nano, emacs and even VSCode.
Now, let's assume we created a commit with a generic message (because we were trying out the editor config) and now we want to change that message for something more descriptive. To do that, run the command
git commit --amend -m "More descriptive commit message"
And now a new commit will be created with the message we provided, we could now be ready to push our changes to the remote repo...
But... did you know that the amend flag also works to add additional changes that we may have forgotten and should've been part of the previous commit?
In that case we have to add the changes before amending the commit withgit add .
orgit add -A
which is the shorthand for--all
.
Difference betweengit add .
&git add -A
The difference relies in thatgit add .
only adds files in the current directory where you're located whereasgit add -A
add the files in the currentand in any subdirectories as well, hence the "all".
Ok, we added the necessary files, commited them and now we're ready to push them to the remote. We do so with the command
git push origin {branchName}
If it's the first time we're pushing this branch to the remote, we can pass in the--set-upstream
flag or-u
for short like so
git push -u origin {branchName}
And now, every time we want to push new changes from that same branch we can just rungit push
and Git will know what remote we're talking about.
We can now see the commit history in the remote repo navigating to the URL we see when running thegit remote -v
command.
Undoing changes pushed to a remote
Now let's assume that we pushed the commit to the wrong branch (maybe because we were so busy paying attention to the difference between the flags to pass to git add...)
Don't worry we can fix that issue with thegit revert
command.
Suppose we have the following history in ourgit log
And we want to remove that last commit from the branch that is on and maybe move it to a different one.
In that case we would run the revert command like this.
git revert 0a995a8
And now Git will create arevert commit with the changes of the previous commit undone.
(You could also have used 'HEAD' instead of the id of the commit with the same result, but I think it's easier to understand what Git is doing using ids instead of pointers to commits.)
What's left to do now is to push this new revert commit to the remote (and if you work with others, tell them to do a pull so they can get the fix.)
That wasn't too bad was it? although if we want to be more cautious for next time, we can avoid doing a revert commit and handle the commits locally.
Moving a commit from one branch to another
Let's see how we can move a commit. There are a couple of ways of doing it, like most things in Git.
Let's imagine that we are in the 'feature/about' branch and we found something to fix in the contact section and committed it there.
We'll now want to move that commit to a different branch like 'feature/contact'. For that let's run the command
git checkout feature/contact
Now we're in the contact branch and if we inspect the log, we'll see that the commit is now in both branches and what's left is to remove it from the first branch.
So now let's go back to the previous branch (withgit checkout -
remember?) and we'll take the id of the commit that's before the one we want to remove and run the command
git reset --hard {commitId}
We'll get a message from Git saying that 'HEAD is now at {previousCommitId} {previousCommitName}'.
So essentially the HEAD pointer moved back one commit and it's like that latest commit was never created in the first place, but it still exists in the branch that we want it to be.
Another option to do it is to use thegit cherry-pick
command.
For instance, if we're in the 'feature/about' branch, make note of the commit id (the one we want to copy) and then move to the wanted branch and run the command
git cherry-pick {commitId}
Now the changes of the commit from the other branch will be applied to the branch that we're on.
Note that cherry-pick applies the changes of the selected commit by creating anew commit on the branch instead of copying the entire commit.
We'll now have to go back to the other branch and remove the commit from there like we did before.
Also note thatgit cherry-pick
works if we want to takeone commit from a branch and copy the changes into another branch whereas withgit checkout
we're taking all the recent commits and moving them to the other branch.
With that, we have moved a commit to it's corresponding branchbefore pushing to the remote which makes things easier to deal with locally.
Getting into more advanced stuff
We'll now be looking into how to handle commits across different branches and remotes with some of the extra firepower that Git gives us.
But you know what? I just looked through the whole article and realized that's it's getting quite long and unwieldy.
So I'll be saving the advanced stuff for a Git tricks part 2.
In that one we'll be looking at things like...
- The different options that
git reset
has. - How to recover commits that may seem lost with
git reflog
. - Doing forced pushes with caution using
--force-with-lease
instead of--force
. - And how to manage changes, commit messages and more with
git rebase
.
So, there you have it, some extra tricks that your probably didn't know when using Git for the traditional software development workflow.
I hope this has been useful, I know a couple of years back I'd be using Git without understanding most of its power and just limiting myself to the most used commands and nothing more.
And now that was it for this week's post!
T Hanks for reading so far and I hope to see you the next week for part 2!
Top comments(2)

Interesting article, thanks, though I believe this is not quite right:
Let's see how we can move a commit. There are a couple of ways of doing it, like most things in Git.
Let's imagine that we are in the 'feature/about' branch and we found something to fix in the contact section and committed it there.
We'll now want to move that commit to a different branch like 'feature/contact'. For that let's run the command
git checkout feature/contact
Now we're in the contact branch and if we inspect the log, we'll see that the commit is now in both branches and what's left is to remove it from the first branch
I think this is true iff:
- feature/contact is a brand new branch you want to split from the current state of feature/about
- the command you use is
git checkout -b feature/contact
But I don't think it would be true if feature/contact is an existing branch split off earlier, is that right?
I've mostly ignored cherry picking, so I greatly appreciate your simple, clear explanation, I'll be looking forward to part 2.

- EducationComputer science & software engineering
- WorkFreelance writer & web developer
- Joined
Hey Jerry,
Thanks for the comment. You are right, that example would only work if the 'feature/contact' branch was created off of the one we're currently in and not if it already existed.
I think that it's not obvious reading that part again, so appreciate the clarification.
I'm making a small project to use as an example for the followup of this article so it took me longer than expected to writing it 😅
For further actions, you may consider blocking this person and/orreporting abuse