Three Things I've Learned This Year

Danny Brown, Senior Developer

Article Categories: #Code, #Back-end Engineering

Posted on

Here are the three most important ways I've grown as a developer in my first year here at Viget.

A question in my one-year review at Viget prompted me to think about ways that I have become better as a developer over my first year. Initially, as I reflected, I only thought of many small things. On reflecting further, I've been able to condense them into three main areas. Hopefully, other new (or experienced!) developers can empathize or even take away some information from these three topics.

1. My knowledge of git #

Git knowledge going into my first year at Viget was pretty much:

  1. Creating/swapping branches (git checkout)
  2. Pulling (git pull)
  3. Pushing (git push, often with -f because that one always worked!)

Since my experience with git largely came from group projects in Computer Science classes, there was never a need for a deeper understanding. I could do the three actions listed above, and I never really ran into an issue. However, knowing those three only gets you so far in the real world. Thus, when starting at Viget, there were a few things I had to learn.

I was aware of the danger in the way I used git before, so I always made sure to check in with my coworkers or manager to make sure I wasn't about to brick something. I realized that many well-secured projects on git/github had protections in place to stop newbies like me from issuing destructive commands to any branches that mattered. While these protections were a safety net, I had to learn some new tricks too. These were needed not only to avoid destructive commands, but also to allow for the parallel flows needed for every developer on a project to work simultaneously.

Gone are the days that we are working on a project with a group of 3 people and I can just say "Hey, don't make any edits to file.py until I push this up." It was bad practice then, and it's absurd to think about doing now.

Here are the commands that I have utilized the most in the last year.

Rebase #

https://code.tutsplus.com/tutorials/rewriting-history-with-git-rebase--cms-23191

I honestly think that the rebase was one of the single most helpful commands I learned to use. Properly issuing an interactive rebase with git rebase -i <branch> led me to pretty much a one-stop shop for some of the things I always had to google before. Running an interactive rebase allows you to:

  1. Bring your branch up to speed by changing its base to the base of an updated branch (which will introduce the most recent commits to your branch before you merge it in)
  2. Rename and squash commits
  3. Avoid the problem of the ugly merge commit
    • It hadn't really bothered me before, but when you actually need to look through the commits, merge commits just add so much unnecessary noise

Chris Jones, a development director here at Viget, has one of the most helpful articles on fixing a tricky situation with rebasing. I'd highly suggest taking a look or bookmarking this article. #thanks-chris

Bisect #

https://www.sumologic.com/blog/who-broke-my-test-a-git-bisect-tutorial/

git bisect is a powerful way to find the (first) commit that caused a certain bug. It works by taking in a commit that doesn't have the bug, and a commit that does have the bug. These are called the 'good' and 'bad' commits

Once these are identified, git bisect becomes similar to an installation wizard, taking you commit by commit until you find the original bugged commit.

Using a binary search, bisect jumps back and forth between known good and bad commits until it finds the commit that introduced the issue. This article was especially helpful in my understanding of bisect.

diff3 #

imgflip.com

No one likes to hit conflicts in git. Things are made even harder by the default conflict style. It can be hard to tell what the original lines were before the incoming and current changes updated them. A way to see the "common ancestor" between them is using diff3. Here is a (simple) merge conflict shown in the default style.

<<<<<<< HEAD
 print(B)
=======
 print(C)
 >>>>>>> merged-branch

While that may be enough information needed to decide which version of the line to take, enabling diff3 allows us to see what the line was before either change.

<<<<<<< HEAD
 print(B)
||||||| merged common ancestors
 print(A)
=======
 print(C)
>>>>>>> merged-branch

To enable it globally on your machine, run git config --global merge.conflictstyle diff3

2. My use of aliases/abbreviations #

https://fishshell.com/

Throughout my first year, I switched between multiple shells. I stared with ZSH, then used Bash, then finally landed on Fish. Regardless of which shell I used however, the common denominator was that I used aliases. Aliases/abbreviations are shorthand commands you can customize for your shell to quickly execute more complicated commands. Writing docker-compose up/run/build many times a day can just get annoying. Luckily, aliases and abbreviations are a perfect solution for this problem.

Since I am currently working in fish, that is the shell I will be providing helpful abbreviations for. For other shells, the syntax for adding the command might change, but the alias/abbreviation itself might still prove useful.

In fish, an easy way to create an abbrevitation is something like this: abbr grc git rebase --continue. That is telling fish that you are creating an abbreviation called 'grc'. Whenever you type grc in the future, it will expand to be git rebase --continue.

Here are some helpful aliases/abbreviations for Git and Docker I have for my fish shell

  • gl -> git log --oneline
    • git log --oneline is a very useful variant of git log. It allows the commit history to be shown in a succinct way
  • gco -> git checkout
  • gap -> git add -p
  • gc -> git commit
  • gst -> git status
  • gpo -> git push origin
  • dcup -> docker-compose up
  • dcr -> docker-compose run

3. My knowledge of Docker #

https://www.docker.com/

One of the largest time sucks I found when I was just starting at Viget was getting a project properly installed. I had to quickly learn some tools for version control like asdf, and even then I still had a good amount of trouble. If I was swapping between a project from 10 years ago for maintenance work that used Ruby 1.9.3 and Postgres 9.2.2, and a project that used Ruby 2.3.7 and Postgres 11, it required at least multiple commands and at most a session of headaches to get everything properly working.

Luckily, before I had to struggle with this problem for very long, Viget started working toward Dockerizing everything. To put it simply, Docker makes it easy to build and run code. There are tons of good articles on what Docker is and why you should use it, but a simple win for me here is that, if projects are Dockerized, then I wouldn't have to worry about using a version manager and hopping around versions, since I could just run a single command that, for the most part, worked on every project: docker-compose up.

Docker brings along its own host of challenges, since it can be decently difficult, at least for me, to wrap your head around. So while dockerizing a project may not be the easiest task, once it is dockerized it makes it incredibly easy for newer devs to a project to get started without hassle. So I'd recommend using it and ideally investing time in learning how to dockerize projects.

Lazydocker #

https://github.com/jesseduffield/lazydocker

Lazydocker is a way to see a birds-eye view of your running containers. It allows you to select the different containers, and press keys to take action. For example, you can restart a container by selecting it and hitting the r key on your keyboard

If you invest time into Docker and useful resources associated with it, it will help you avoid the time suck of setting up new projects.

In Conclusion... #

While I certainly learned more than just those three topics in all of 2020, they seemed like the three that most accelerated my aptitude as a developer. Upgrading my git knowledge helped me collaborate better with my team. Adding abbreviations and aliases helped me cut down on time remembering and/or mistyping longer commands in the shell. Utilizing Docker to the fullest extent helped both myself and other team members get projects running locally incredibly quickly.

Hopefully, my experiences or some of these tips will help other developers, old and new!

Danny Brown

Danny is a senior developer in the Falls Church, VA, office. He loves learning new technology and finding the right tool for each job.

More articles by Danny

Related Articles