How to get somebody fired using Git
Tags: git, coding, github, learning
Published: 2024-04-02 19:58:32

## This is Billy. 

![Stick figure with a smile and a red tie](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zi8n22y9i5j499h2bvx7.png)
He is a trainee developer working for an important company.

Unfortunately for the company, today Billy has woken up and chosen _violence._

This is because he finds learning Git very troublesome, boring and convoluted. 

Branches, commits, checkouts, HEADs, features, staging, oh my! 

It was just too much for him.

But then Billy had the absolutely best worst idea.

> "What if I learn git by first learning what NOT to do, but then doing it anyway!"

This would accomplish three things:

1. He would learn git's most common tools by giving himself fun little challenges that would normally be prohibited.
2. If he learned what **not** to do, he could then later focus on what he **should** do.
3. Learning this way satisfies his chaotic evil tendencies. 
 
This was sounding more and more like a good idea to Billy. This would definitely make him a better developer.

There was just one problem though...

### Git is a version control system used by developers to manage source code for software. 

Whenever something is changed, added or even deleted by somebody, Git registers who did what. 

If you wanted to do very bad things in, let's say, a repository owned by the company you work at, somebody could always trace it back to you.

And that would DEFINETELY get you fired. 

So that's why Billy stole Trent's computer.

![Billy the stick figure holding up a realistic laptop that reads "Trent's computer (Stolen)"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dgqmz1otq6yqcqj3vsf.png)

Trent is a big dumb-dumb who left his computer on and unprotected when he went to the bathroom.

He also ate the last slice of pizza at last month's after party without asking first.

With Trent's computer, Billy now has access to the same repositories, but under Trent's login credentials.

And so now Billy can learn Git by first learning everything he shouldn't do, like:

## 1. Pushing code to somebody else's branch with --force

Let's say the current git ecosystem looks like this:

![Git Diagram of main and the co-worker's feature branch.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d6jhhy9i977la225uatn.png)

Billy is currently checked out on an earlier version of another co-worker's branch. 

This can happen if 2 people are checked out on the same branch, but one of them starts pushing changes to the remote.  

This means that Billy is behind on the branch. If he wanted to get the latest changes of the branch he currently is on, he would write into the terminal `git pull`

Fun fact:
Git pull is actually the combination of 2 other git commands.

* `git fetch origin` (which fetches the latest changes of remote WITHOUT checking out or merging it)
* `git merge origin/<branch name>` (which _does_ merge your local changes to the remote. Since normally you wouldn't have local files to merge, git does what's called a "fast-forward" and you end up with the latest changes)

Billy wonders what would happen if he tried pushing on this person's branch, even if he's behind on the latest changes.

Normally if he tried to `git push` some code, the attempt would fail with an error - Asking him to pull the latest changes first.

(This is a safety net that's built into git to avoid having work be lost. You can't push unless you pull first!)

But Billy can avoid this if he did a `git push --force` command.

`git push --force` is usually a big nono for developers. It's a command that forcibly overwrites the git history and lets you push your local changes despite it possibly deleting other people's work on the same branch.

Billy has never used it before and is a curious boy, so he did what any curious person would do.

1. He created a new file with special text inside:
`echo "Trent was here" > Trent.txt`

2. He committed his very important changes to the branch
`git add Trent.txt`
`git commit -m "Trent committed this"`

Which makes git look like this:

![Git flow diagram showing how his co-workers changes disappear and Billy's new code overwrites it](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3wzzbao8zv2mbs9ciuqy.png)

3. He finishes by force-pushing his new changes to the branch
`git push --force`

After a few seconds...

*Poof!*

Billy's very important changes are now in Git!

And at the same time, all of his co-worker's work completely disappears!

If only Billy had used `git push --force-with-lease`! 

`--force-with-lease` is the safer version of the `--force` command. It would have prevented Billy from ever overwriting his coworker's work on the remote.

Oh well! What's done is done. And in the end, having fun is what matters. 

Billy wonders how long he has before that co-worker notices.

He also wonders if there's something that's even worst he can do. Maybe... he can do something similar in Production?

A light bulb goes off in Billy's head! What if he did a:

## 2. Hard Reset on the production branch

`Git reset` is a command that, similar to what Billy did to his co-worker, undo's the changes that have been created in a branch to a previous commit.

Unlike the `git push --force` command he learned earlier, there's nothing to push. It just rewrites the git history by (usually) uncommitting everything done up to a certain commit.

There's 3 modes to the git reset command.

1. `git reset --soft` which moves HEAD (Head being the commit you're currently checked out on) back to the specified commit, while also undoing all the changes made. All those changes go back to staged and allow you to commit again.

2. `git reset --mixed` does the same as `git reset --soft`, but leaves all the changes you've made unstaged. This is also the default mode for the git reset command. So if you write `git reset`, that would be the same as doing `git reset --mixed`.

3. `git reset --hard` is diabolical. Instead of undoing the changes and leaving them in staged / unstaged... it just discards them.

*Poof*

All those changes disappear when you hard reset to an old commit.

So if Billy were to say... hard reset to a commit that's from, oh I don't know, **6 months ago**, that would be very bad for the company.

Billy smiles as he opens up the terminal.

Remembering what the git ecosystem looks like:


![Git branch showing the 6 month old commit and the latest one](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xwvqa9275q5f4f9oa1p.png)


Billy happily starts:

1. Typing into the terminal `git checkout main` which positions him on the latest commit of that branch.

2. Uses a git visual tool to find a commit from the main branch that's 6 months old.

3. Types `git reset --hard <commit hash>` to erase all the changes in the main branch from the last 6 months locally.

4. Finishes off by using our good friend `git push --force` to permanently leave his local destructive changes in the remote.

After a few seconds...

*Poof!*

Billy successfully made some company executives very very angry!

But wait a minute...

It's weird that Billy was able to do that, wasn't it? After all...

### Permissions are usually set in repositories so that nobody can push to the production branch directly. 

This prevents accidental pushing or rewriting of git history that affects the website directly.

That's why something called a "Pull Request" (or a PR) exists. 

### A pull request is a proposal to merge a set of changes from one branch into another.

And normally, other tech savvy developers first have to accept your changes before you can merge anyway.

But what happens if those permissions are never set?

Well, seems like anybody like Billy can come and erase everybody's hard work from the last 2 quarters in a second.

He calculates he has maybe 10... no, 15 minutes before his changes to main impact in production.

So Billy has to act fast. He has time for maybe one more chaotic evil thing before somebody named Trent gets in trouble.

What to do...

OH, Billy knows! He should:

## 3. Expose the project's secrets and push it to production!

Billy can easily do this by modifying the .gitignore file.

### .gitignore is a special type of file located in your project's directory. As the name implies, it specifies which files Git should ignore and avoid letting you stage.

This is super helpful when you have particular files you never want to upload to your repository in the first place.

One of those files you _normally_ want to avoid uploading are your .env files.

### .env files tend to be used in projects to hold environment variables you would use throughout your solution.

They feature key/value pairs with information you _really really_ don't want to upload. Things such as API keys, database URIs, AUTH secrets and more.

But Billy doesn't believe in keeping secrets to oneself.

He is the hero of his story and must let the people know!

So if we assume our .gitignore files looks like this:

```
# Javascript node_modules
node_modules/

# API keys
.env
```

Then all Billy has to do is:

1. Locate the .gitignore file

2. Use his favorite IDE or terminal text editor to remove the .env line from the file and save it. (Which makes the file now look like this)

    ```
    # Javascript node_modules
    node_modules/
    
    # API keys are gone from ignore oops
    ```

3. Add the now changed .gitignore file to staged. Billy does this by typing `git add .gitignore` into the terminal

4. Oh wait! Don't forget - Since Git now isn't ignoring the .env file, Billy has to add that too! `git add .env` is typed into the terminal as well.

5. Time for committing! Billy does this with this line: 

    `git commit -m "FREEEEEEDOOOOOMMM!!!! #TrentWasHere"`

6. Final step! Time to push to the main branch. And since again, for some reason there isn't any permissions set that would stop Billy, he can write `git push --force` into the terminal.

After a few seconds...

*Poof!*

"Liberté, égalité, fraternité" whispers Billy with glee! Right as he leaves Trent's computer where it belongs.

Good thing too, as he just heard the sound of a toilet flush from a room away.

Billy runs back to his desk, making it just in time before anybody notices.

*Phew*

Seems like Trent finally came back from his bathroom break and sat down at his desk.

But right before he could even open his laptop, Trent's phone started ringing.

*Ring ring, ring ring*

Billy waited in anticipation as he saw Trent slowly pick up his phone.

"Hello?"

"TRENT. OFFICE. NOW."

Billy could hear the yelling from Trent's phone from 5 desk's away.

"WOAH what happened boss?"

...

"I didn't do anything lik-"

...

"What do you something happened to production?

...

"I'm on my way"

And as Trent quickly runs to the office, probably for the screaming of his lifetime.

Billy sits back, relaxes and can finally say:

"I'm a better developer today".

![Billy the stick figure is smiling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7627w4yj05yxqwiomyty.png)

---
## This was the dumbest article I have ever written.

If you like my sense of humor then I think you'll like my newsletter "Exceptional Frontend" - the most entertaining front-end newsletter on the web.

It's for any devs out there that want a front-end centered newsletter that tries to be different from everybody else. Big focus was put into making it unique and most importantly — FUN!

While also at the same time helping devs become exceptional at what they do.

[You can sign up here.](https://exceptional-frontend.ck.page/sign-up)