Git Git Git! One of The Most Important Utilities in History, Git Tips and Experience!

Hocky Yudhiono
11 min readFeb 27, 2022

I’ve been using git for 6 years now 😎.

This is my take on writing about git tips. When first I started programming, I think to myself. Git is a simple version history program, everyone knows about that. But I wonder how to use it. Then I thought, why not use google drive? It’s easier.

Then here comes the most powerful feature — In my opinion, the git branch! So powerful! Yet, this is the core power of git as everything revolves around it. Now, I will discuss some git tips that should be important to all those “beginner” git user, and with this, will not explain the basic “kindergarten” git stuffs, but will advance you to a whole new git user level.

After some considerations (hehe 😆) Maybe I will just write some basic git stuffs as well so you can get a glimpse of what we’re working in case you’re a beginner. —I assume 99% you aren’t— You can skip to the more advanced tips part at the bottoms.

Step 1: Two Ways to Start Working on Git

On a working project root directory, you can start by doing:

git init

Should be the first command on how to initialize git in your folder.

Or you can basically just open your favorite cloud git repository, and do

git clone [URL] [folder-name-in-local : OPTIONAL]

to clone an existing repository.

What is the Difference Between HTTPS and SSH?

SSH intuitively is a way to authorize yourself in the system. — Not really the true definition, you should google this for more information —

You can create a key-pair that you can read more about here https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent.

Then in your settings of the cloud repository, paste the public key to the text box (by default, should be in your $USERS/.ssh/id_rsa.pub

And by this way, you don’t need to give username and password for git again when you’re trying to connect to cloud. This will be your “Token” to login into the cloud repo. This is example for github, you can do the same with gitlab, or any other git cloud.

Now, you can do git clone using the SSH url. If I’m not wrong, https://gitlab.com already encourages using SSH because it’s basically “Safer” as you don’t really need to use your main account each time you login, and each access of SSH key from different devices can be logged. So you know if there’s a bad guy 😈 trying to access your repository.

The Git State

When using git, there are 3 states of repository:

  • Modified state: When adding, changing, or removing anything in a file, git notices something but we haven’t staged those changes yet. After you do git add . or any git add commands, this will change to staged state.
  • Staged state: This is when we inform git that we’re taking note of those changes. Per se, this is noted per files.
  • Commited state: This is when you tell git to take a snapshot of the staged state. The staged files can be snapshoted into this realm.

Git Checkout

After talking about state, I wanna explain the concept of branch. In github, each commits can have multiple parents. What branching does is to create a new “timeline” that is different from the current ones. To create a new branch you can use

git branch [new-branch-name]

To go to a certain branch, you can use

git checkout [branch-name]

or you can do both within the same command:

git checkout -b [new-branch-name]

To checkout all the branch available, you can use

git branch -av

-a flag is to show all branches, including the remotes ones, while -v flag is to show verbose latest commits of each branches.

How To Commit

To commit a staged file, you can do

git commit -m "[Your message]" [specific files: OPTIONAL]

If you want to commit only specific files, I recommend you to use a graphical user interface, usually built in alongside with an IDE or your lovely code editor 💗.

Working with Remote Branch

In git, there is a thing called remote

A remote in Git is a common repository that all team members use to exchange their changes. In most cases, such a remote repository is stored on a code hosting service like GitHub or on an internal server.

What is HEAD

So, git works using pointer for each commits, quoted from http://git-scm.com/blog:

The HEAD in Git is the pointer to the current branch reference, which is in turn a pointer to the last commit you made or the last commit that was checked out into your working directory.

In simple, HEAD is a reference to the current commit on the current branch, in a single time, there can only be one HEAD referencing a commit in a certain branch.

The content of HEAD is stored inside .git/HEAD and it contains the 40 bytes SHA-1 of the current commit.

Of course, there is something called the Detached HEAD, so you can move your HEAD to a previous or prior commits

git checkout HEAD~X // x is the number of commits to go back

To check the history of HEAD moves, you can do git reflog. or in a more explainable way, reference log 😆. The latest changes goes on top. You can also move your HEAD to pre-existing commits by using git checkout [commit-hash]

I actually want to explain more about git restore and git switch, but the use case can be handled with git checkout and some googling when you're encountering an issue 😂. So I'll leave this for the next opportunity.

Reference:

Remote and Working with Cloud ☁ Repository

Remote is like a reference for remote repository. You may also have heard of the terms “origin”.

In Git, “origin” is a shorthand name for the remote repository that a project was originally cloned from. More precisely, it is used instead of that original repository’s URL — and thereby makes referencing much easier.

Note that origin is by no means a “magical” name, but just a standard convention. Although it makes sense to leave this convention untouched, you could perfectly rename it without losing any functionality.

To checkout available remote you can do git remote -v

Which will show its name and the URL reference. Now you can do git pull. This, can sometimes show up. Why? I will explain.

There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

git branch --set-upstream-to=<remote>/<branch> master

Upstream is the reference for the remote branch from our local branch.

The term Tracking means that a local branch has its upstream set to a remote branch.

To see what branch tracks which branch, it’s stored in the local .git/config file. Just do cat .git/config or type .git\config if you're using windows to see the tracks.

When a local branch is started off a remote-tracking branch, Git sets up the branch (specifically the branch.<name>.remote and branch.<name>.merge configuration entries) so that git pull will appropriately merge from the remote-tracking branch.

This behavior may be changed via the global branch.autosetupmerge configuration flag. That setting can be overridden by using the --track and --no-track options, and changed later using git branch --set-upstream-to.

About git config, I will explain it in the next section. Quoted from the stackoverflow below, having an upstream branch registered for a local branch will:

  • tell git to show the relationship between the two branches in git status and git branch -v.
  • directs git pull *without arguments* to pull from the upstream when the new branch is checked out.

In short, you can do:

git branch -u [upstream-name]/[remote-branch-name] [local-branch-name]

To set upstream so you can git pull and git push accordingly. Extra notes, see that git can’t merge unrelated history as well, so it’s kind of safe to accidentally set up different remotes for a repository.

References:

Git Config

This basically is the config file for your git. It has settings and flags you can explore! To see the global config, you can do git config --list --global or use --local to see the local config. This sometimes be used when configuring (end-line carrier space between UNIX and DOS or just setting up your account config, or any customizable preferences 😆)

Rename Commit Message in Git

It’s hard to do it using the plain CLI. But chill, there’s a lot of good Git Client that can do this easily with friendly Graphical User Interface. My favorite one is Git Tower (Not sponsored lol, but thanks for providing us, students with free education plan 💖💖💖) You can grab it here https://www.git-tower.com/

Merging Branches

Beside splitting, you can unify branches, essentially, all the changes can be unified/merged using git merge [branch-name-you-want-to-put-in-current-HEAD] That's it. Then, sometimes you'll be given a merge conflict, that's when git cannot resolve the conflicts, you must manually do it. I really recommend you to use an IDE to do this 😭. Intellij IDEA or VS Code got a nice git conflict resolver!

The Secret Ingredients and About Git Diff

There are a lot of hassles and things going in our code. So many different files move. The secret is, SHA!, or a hashing system! + Graph!

Git is actually a one giant directed acyclic graph. all commits references their parent. HEAD itself is a special pointer to the latest commit. It moves automatically!

Each file in git has a 40-char SHA and everything is kept track by hashes, each objects, branches, commits, and everything have a SHA hash.

Git has been going through lots of winds and storms. Git offers different git diff algorithms! Not so many people know about this, but this is really cool! Git offers four diff algorithms, that is Myers, Minimal, Patience, and Histogram. By default it uses Myers.

All diff algorithms will result in correct output, but sometimes the diff outputs can be different. If you are really curious about this, you can actually change it by using the ‐‐diff-algorithm flag.

Why You Should Not git add . lol

I always did this. Why? Because I only change the important parts of stuffs when coding. Until one day. Stupid me did something amazing.

There is a .env files that provides example by default. It has login credentials waiting for you to enter it there. It was a public repository and voila!

I accidentally added, commited, and pushed my password to the whole world!

So, there are several tips for you that you can utilize when working with git.

  • You may git add ., but before doing it, you should do check git status to see what files you are adding.
  • Do git diff to make sure all your changes are correct, especially before you're staging lots and lots of files. (this will only check unstaged files diff)
Git diff on action

Okay, second problem

OH NO! I staged lots and lots of useless files!

What is this weird files with un~ files extension, or what is this .idea/ folders!

  • Go learn vim, you should know basic commands. I’m assuming you’re using vim as your main editor:
  • Abort your commit by doing :q!, this means exit without saving any commit message.
  • Add a .gitignore file.
  • Do git rm -rf --cached . To unstage all changes (but still keeping those changes) and do your lovely git add.
  • Voila! Another day saved!

Fruit Picking 🍍, Cherry Picking 🍒, Commits PICKING 🔥!

You can cherry pick (put a commit into your branch from another one by doing git cherry-pick [commit hash].

But yes, this feature is kinda tricky and lots of special conditions to use this, as you must do it sequentially and carefully. But you should know about this feature!

Dangerous Stuffs

Do you know you can remove all those ignored files that are still in your working repository?

Go do git clean -xdf. -d will remove directories as well, and -f will force cleaning (needed by default).

If you haven’t commited any changes, but there are unstaged files and staged files and you want to start all over, go do git reset --hard.

If you want to be in a commit position in the large git graph, you can do git reset --hard [commit hash]

If you don’t wanna do --hard, you can check out:

  • --soft: uncommit changes, changes are left staged (index).
  • --mixed (default): uncommit + unstage changes, changes are left in working tree.
  • --hard: uncommit + unstage + delete changes, nothing left.

Then if you wanna update your cloud repository, just go git push -f. Voila. Time travel!

Do this with your own risk!

I accidentally deleted some of my course notes because of this.

Other Git Features You Might Find Useful

  • Git hooks and precommit. When you’re doing git commit, you can assign some other hooks of shell commands, I won’t explain it too much in this blog, but you can assign some linters before commiting! This is one of the important clean code stuffs right?
  • Git rebase — this is like rewriting commits, kinda tricky to explain, but rather than the usual workflow of merging two branch into one, rebase is basically appending those commits into the stream line.
  • git log to check the history of this repository
  • You can actually restore hard resetted files. Don’t panic and just google it! I did this once.

Writing This Part for⠀ “̶F̶o̶r̶m̶a̶l̶i̶t̶a̶s̶ ̶A̶j̶a̶ ̶U̶n̶t̶u̶k̶ ̶B̶l̶o̶g̶ ̶t̶e̶n̶t̶a̶n̶g̶ ̶G̶i̶t̶ ̶P̶P̶L̶ ̶2̶0̶2̶2̶”̶⠀Showing Off What My Software Engineering Project Would Look Like

You can google translate that joke (🤡 hehe) sentence if you don’t understand Bahasa Indonesia. In my software engineering project, we’re working using different branches. The conventions are:

  • master, Production ready code. Gonna be updated every sprint by the authorization of the lecturer and/or product owner.
  • development/staging, Development code. Before putting it into production, this is the bowl 🥣
  • feature, denoted by PBI prefixed branches: Implementation of a product backlog item.
  • coldfix, where staging code should be fixed.
  • hotfix, where master code should be fixed.

I’m currently not really familiar with TDD as the project assigned to our team is a mobile application, using React Native. I feel TDD is a burden as I don’t know yet how to test the app. But I believe I’m a quick learner and a good programmer, so any hard stuffs won’t be hard for me 😎. We’re using this convention when commiting changes.

Description shall use imperative mood and descriptive, but not too long. We’re also assigning reviews to each others. So our code is maintained.

  • [RED] <description>: Test stage
  • [GREEN] <description>: Code fixing those tests
  • [REFACTOR] <description>: Improving those codes
  • [CHORES] <description>: Non-functional codes

--

--

Hocky Yudhiono

Fullstack Developer 💻, Competitive Programmer 🐭, Blogger 📝, Eager Learner 💤 | https://hocky.id/