If git merge feels noisy, that’s because it can be. Lots of noisy merge commits make history harder to scan, especially when you’re just trying to understand what actually changed. git rebase takes a different approach: instead of creating a merge commit, it replays your branch commits on top of the latest base commit so your history stays clean and linear.
Git is distributed, which means your repo and my repo can both be valid “sources of truth”. In practice, teams usually pick one remote as the shared source (often GitHub) and sync local work against it… but that’s just a convention. Let’s dig into how syncing Git repositories to GitHub works, and how that’s just one way to work with Git.
If you’ve ever made a commit and immediately thought “noooope”, then git reset is what you need. It’s one of the most useful Git commands for undoing work, but it’s also one of the easiest to misuse. The --soft version is usually safe and predictable. The --hard version is powerful and can absolutely nuke your local changes.
Git is the open-source command-line version control tool, and GitHub is basically just a collaboration on top of it. You can absolutely use Git without GitHub, but for most teams, GitHub (or something similar) is where a lot of the collaboration happens. Linus Torvalds created Git, and… well we don’t talk about who owns GitHub these days…
Many devs adopt the git add . (yolo, just yeet it all into the commit) workflow. It is fast, simple, and usually correct. But eventually you’ll have files in your repo directory that should never be committed: secrets, generated artifacts, dependency folders, and random local junk. That’s what .gitignore is for.
A Git branch allows you to keep track of different changes separately. For example, you can create a new branch to experiment with changing a color scheme without affecting your primary branch. If you like the changes, you merge (or rebase) the branch back into main. If you don’t, you delete it.
Git stores author information so that when you’re making a commit it can track who made the change. Here’s how all that configuration actually works.
Git is the distributed version control system (VCS). Nearly every developer in the world uses it to manage their code. It has quite a monopoly on VCS. Developers use Git to:
Let’s take a look at some of git’s “plumbing”, that is, the commands that are mostly used for working “under-the-hood” with Git, and that you’ll only use if you’re trying to debug your Git files themselves.
“What’s the point of having multiple branches?” you might ask. They’re most often used to safely make changes without affecting your (or your team’s) primary branch. Once you’re happy with your changes, you’ll want to merge them back into main so that they make their way into the final product.
To someone who isn’t familiar with these roles, it’s easy to think that DevOps and systems reliability engineers (SREs) might have the same job. After all, both of them involve automation, coding, scaling, and reliability to one degree or another. Both roles are trying to make an organization more efficient. It’s reasonable to wonder if there’s any daylight between DevOps vs SREs.
Doesn’t it seem like every day there’s a new mishmash of responsibilities into a job title? One day soon, someone will be hired as a DevOpSysSecInfraArc engineer.
The deeper you get into the tech sphere, the more unintelligible the job titles seem to be. Plus, the same title at different companies often encompasses different responsibilities. Ask twenty data scientists what they do and you’ll get twenty different answers.
The median DevOps engineer’s salary is $103,994 in base pay, with around $28,514 in additional pay through bonuses, commissions, and profit sharing according to Glassdoor. Salary.com estimates the average is closer to $125k, while BuiltIn puts the average closer to $128k in base pay, with an additional $15k in cash compensation.
It’s time for some speculation on my part I believe that the job duties of “back-end” and “DevOps” engineers will coalesce to include almost everything that “the user doesn’t see”. There will still be room for specialization, but these roles will become less distinguishable overall.
DevOps principles, and CI/CD specifically, are generally presented as a more efficient way to run a software development organization. While I hold the belief that CI/CD is more efficient and effective than manually testing and deploying code, I’d like to talk about something we don’t bring up quite as often.
“DevOps” is one of the most misunderstood terms in the software development industry. To be clear, I’m not the arbiter of truth when it comes to the definitions of words. That said, I’m here to say two things:
Where I work, we use a repo-per-namespace setup and so it often happens that I want to restart all pods and deployments in a single Kubernetes namespace. Maybe I want to see the startup logs, or maybe I want to shut down production for a few seconds. Don’t question my motives.
My worst enemy is processes that a developer spun up years ago on a server everyone has forgotten about. I don’t know how to find these systems reliably, I don’t know where they came from, what depends on them, and if they are safe to delete. For example, the dreaded 15 6 2 1 * /home/lane/backup.sh. You may recognize this as a Unix cronjob, a job that is scheduled to run on a server periodically.
This is a tutorial on how to set up an Electron app on Travis CI, so that new versions are deployed to GitHub Releases with a simple pull request.