Search
30 results for “git”
Search results
Git Fundamentals
How the working directory, staging area, and commit history actually relate to each other, and why understanding that three-stage model makes branching, rebasing, and undoing changes stop feeling arbitrary.
GitOps Principles
Why treating Git as the single source of truth for cluster state, instead of running kubectl/terraform apply by hand, changes how deployments, rollbacks, and audits actually work.
What is the difference between the working directory, the staging area, and a commit in Git?
The working directory is the actual files on disk, whatever state you've left them in. The staging area (the "index") is a snapshot of exactly what will go into the next commit; `git add` copies changes from the working directory into it, one file or hunk at a time, which is why you can commit only part of what you've changed. A commit is a permanent, immutable snapshot of the staging area at the moment you ran `git commit`, plus a pointer to its parent commit, which is what forms the project's history graph. Understanding that staging is a separate, explicit step - not just "what's changed" - explains why `git status` shows both staged and unstaged changes for the same file.
What is the practical difference between `git merge` and `git rebase`?
Both bring one branch's commits into another, but they produce different history shapes. `git merge` creates a new merge commit with two parents, preserving exactly how the branches diverged and came back together; nothing is rewritten, which is why merge is safe on shared/public branches. `git rebase` replays your branch's commits one by one on top of the target branch's tip, producing a linear history with no merge commit, but every replayed commit gets a new hash. That rewriting is why rebase should be avoided on branches other people have already pulled; their history and yours will diverge as soon as they fetch the rewritten commits.
What is the difference between `git reset` and `git revert`, and when should you use each?
git reset moves the current branch pointer (and optionally the staging area and working directory) to a different commit, effectively rewriting history as if the reset-past commits never happened on this branch - fine for commits that only exist locally and haven't been pushed. git revert creates a brand new commit that applies the inverse of a previous commit's changes, leaving history intact and additive. Because it doesn't rewrite anything, revert is the safe choice for undoing a commit that's already been pushed and pulled by others; reset --hard on shared history causes exactly the same divergence problem as a rebase on a shared branch.
What makes a workflow "GitOps" rather than just "we deploy from CI"?
The defining property is a pull-based reconciliation loop, not just that Git triggers a deploy. A GitOps agent (Argo CD, Flux) runs inside the cluster and continuously compares the live state against what's declared in a Git repository, pulling and applying any drift, with or without a new commit. A CI pipeline that runs `kubectl apply` on push is push-based: it changes things once, on trigger, and has no ongoing awareness of whether the cluster later drifts from that state. GitOps closes that loop continuously and treats Git, not the cluster, as the source of truth.
How does GitOps make rollbacks different from a traditional deployment rollback?
In a traditional deploy, rolling back means re-running a deployment process with an older artifact reference, a distinct operation from a normal deploy. In GitOps, a rollback is just a Git revert: since the desired cluster state is fully described by the repository at any commit, reverting to a previous commit and letting the reconciliation loop pick it up produces the previous cluster state through the exact same mechanism as any other change. There is no separate "rollback pipeline" to maintain or that can itself have bugs.
Why does GitOps improve auditability compared to engineers running kubectl or terraform apply directly?
Every change to cluster state has to go through a Git commit, which means it inherits Git's existing history, authorship, and (if branch protection is configured) pull-request review, automatically. Direct `kubectl apply` access leaves no equivalent trail: two changes with the same effect are indistinguishable, there's no required review step, and reconstructing "who changed what and why" after an incident means digging through cluster event logs instead of reading a linear, reviewed commit history.
What do the three digits in a chmod octal mode like 644 or 755 actually mean, and what does a leading fourth digit add?
Each of the three digits is a sum of read (4), write (2), and execute (1), in order for the owner, the group, and everyone else; 644 means the owner gets read+write (4+2), while group and others get read-only (4). 755 means the owner gets read+write+execute (4+2+1), and group/others get read+execute (4+1), the common mode for an executable or a directory that others need to traverse. An optional leading fourth digit sets setuid (4), setgid (2), and the sticky bit (1); setuid/setgid make a program run with its owner's or group's privileges rather than the caller's, and the sticky bit on a directory (classically 1777 on /tmp) restricts file deletion to each file's own owner even though the directory itself is world-writable.
Building a Production-Ready AKS GitOps Platform with Terraform and ArgoCD
The DevOps Project That Finally Made Kubernetes, GitOps, and Terraform Click
A consumer receives a message, starts processing, but crashes before deleting it. What happens to that message, and why is this actually the desired behavior?
Once the visibility timeout expires without the message being deleted, it automatically becomes visible again in the queue and can be picked up by the same or a different consumer for another processing attempt. This is deliberate, not a bug: the alternative (a crashed consumer's message vanishing permanently) would silently lose data, whereas reappearing after timeout guarantees eventual processing at the cost of a possible duplicate attempt, which is exactly the trade-off "at-least-once delivery" describes. Setting the visibility timeout too short causes premature, unnecessary reprocessing of messages still legitimately being worked on; too long delays legitimate retries after a real crash.
What does "at-least-once delivery" actually guarantee, and what does it not guarantee, and why does that mean a consumer must be idempotent?
At-least-once delivery guarantees a message will eventually be delivered and processed at least one time, it does not guarantee exactly one delivery, the same message can legitimately be delivered and processed more than once, for example if a consumer's deletion request is lost after it already finished processing, or a visibility timeout expires just as processing completes. Because duplicate delivery is a normal, expected outcome of this model rather than a rare edge case, a consumer has to be written so that processing the same message twice produces the same end result as processing it once (an idempotent operation), rather than assuming the queue itself will prevent duplicates.
Platform Engineer Roadmap
From orchestration and infrastructure-as-code foundations through GitOps delivery and service mesh, up to building a real internal developer platform, linked into Cloud Tech by Victor topic references.
What's the practical difference between Repeatable Read and Serializable, given that PostgreSQL's Repeatable Read already prevents phantom reads?
PostgreSQL's Repeatable Read goes beyond the SQL standard's minimum and already prevents phantom reads via snapshot isolation, but it can still allow a specific class of anomaly called a serialization anomaly, where the combined effect of several concurrently-committed transactions is not equivalent to any possible serial (one-at-a-time) ordering of them, even though each transaction individually looks consistent. Serializable adds predicate locking on top of snapshot isolation specifically to detect and prevent that remaining anomaly, guaranteeing that the outcome is always equivalent to transactions having run one at a time in some order. The cost is the same as Repeatable Read's, more serialization failures the application must retry, in exchange for the strongest correctness guarantee available.
What is an "LLM-graded" eval, and when would you reach for it instead of exact-match or similarity-based grading?
An LLM-graded eval uses a separate model call to judge a subjective quality of the output, tone, empathy, professionalism, on a numeric scale or binary classification, rather than checking it against one fixed correct answer. Exact-match grading only works when there's one right answer (a category label); similarity-based grading (cosine similarity between embeddings) works when wording can vary but meaning should match a reference. LLM-graded evals are the right tool specifically for qualities that are inherently subjective and hard to define with a fixed rule or reference string, at the cost of being noisier and more expensive to run than a simple string comparison.
What is a "golden path" and why does it matter more than giving teams unlimited flexibility?
A golden path is an opinionated, well-supported, self-service way to accomplish a common task, spinning up a new service, provisioning a database, setting up a CI pipeline, that comes with sane defaults for security, observability, and reliability already wired in. Unlimited flexibility sounds appealing but means every team re-solves the same problems (how do we get logs flowing, how do we handle secrets) slightly differently, multiplying the platform team's support burden and creating inconsistent security/reliability posture across the organization. A golden path trades some flexibility for consistency and speed, while still allowing teams to go off-path when they have a genuine reason to.
Given the risk of hitting a recursion limit, when would you rewrite a recursive algorithm iteratively, and what does that actually trade away?
Rewrite iteratively when the recursion depth scales with input size in a way that could plausibly exceed the platform's real stack capacity, deep tree traversals, recursive descent over large or adversarial inputs, anything where "how deep" isn't bounded by a small constant. The trade is code clarity: many recursive algorithms (tree traversal, divide-and-conquer, backtracking) read far more naturally as recursion, mirroring the problem's own recursive structure, and converting them to an explicit-stack iterative version, while removing the depth risk entirely, usually costs some of that direct correspondence between code and problem structure.
Why should variables almost always be quoted, e.g. `"$name"` instead of `$name`?
An unquoted variable expansion undergoes word-splitting (on whitespace) and globbing (on `*`, `?`, etc.) before the command sees it, so a value containing a space or a shell metacharacter silently becomes multiple arguments or an unintended file-glob expansion instead of one literal string. Quoting (`"$name"`) suppresses both, so the variable's value is always passed through as exactly one argument, which is why nearly every Bash style guide treats an unquoted variable expansion as a latent bug rather than a style preference.
Why would you use a NAT gateway instead of just putting a resource in a public subnet?
A NAT gateway lets resources in a private subnet initiate outbound connections to the internet (to pull a package, call an external API) while remaining unreachable from the internet for inbound connections; the NAT gateway only translates and forwards traffic the private resource itself initiated. Putting a resource directly in a public subnet with a public IP makes it directly reachable from the internet in both directions, which is unnecessary exposure for anything that only needs outbound access, like an application server that doesn't need to accept direct public traffic.
Can Grid and Flexbox be used together in the same layout?
Yes, and in practice most real layouts use both, Grid for the overall page or component structure (header, sidebar, main content, footer), and Flexbox inside individual grid areas for things like a horizontally arranged button group or a centered card. They are complementary tools, not competing ones.
What does hashed sharding trade away in exchange for fixing the monotonic-key hot-shard problem?
Hashed sharding computes a hash of the shard key value and assigns chunks by hash range instead of by the raw value, which scatters even monotonically increasing keys roughly evenly across shards, since consecutive input values hash to essentially unrelated output values. The trade-off is range-query locality: a query filtering a range of the original shard key values (like "the last 24 hours" on a timestamp key) can no longer be routed to one contiguous set of shards, because the corresponding hashed values are scattered unpredictably across the whole cluster, turning what would have been a single-shard query under range sharding into a broadcast query touching every shard.
Why does BFS guarantee the shortest path in an unweighted graph, while DFS gives no such guarantee at all?
Because BFS processes vertices in strict order of distance from the start (via its queue, level by level), the first time it reaches any given vertex is necessarily via a shortest path to it, there's no way to discover a vertex at distance k before every vertex at distance k-1 has already been discovered. DFS has no such ordering property, it commits to going as deep as possible down one path before backtracking, so it can easily reach a target vertex via a long, winding path long before it would have found a much shorter one, there's nothing in DFS's structure that favors shorter paths over longer ones at all.
Why is scanning IaC source (Terraform files) not sufficient on its own, without also checking the plan?
Static scanning of Terraform source can catch some misconfigurations (a hardcoded insecure default) but can't see values that only exist after variables, data sources, and module composition are actually resolved, an insecure setting could depend on a variable supplied at runtime that static source scanning alone can't evaluate. The plan is the fully resolved, concrete set of resources Terraform is actually about to create or change, which is why policy-as-code tools evaluate the plan, not just the source, as the authoritative point to check against before anything is provisioned.
Why is storing Terraform state locally a problem for a team, and what is the standard fix?
Local state is a single file on one person's machine, a second engineer running `terraform apply` has no idea what the first one already created, so both can independently "discover" no matching state and try to recreate resources, or worse, apply conflicting changes concurrently with no locking. The standard fix is a remote backend (S3+DynamoDB, Terraform Cloud, GCS, Azure Blob) that stores state centrally and supports locking, so only one apply can run at a time and everyone reads the same source of truth.
Azure Web App Zero-Downtime Deployment: A Hands-On Guide to Deployment Slots, Auto Scaling, and Load Testing
A practical Azure App Service lab covering staging slots, slot swaps, autoscaling, and traffic testing.
What is the difference between CloudTrail management events and data events, and why does it matter?
Management events record control-plane operations, creating a role, launching an instance, changing a security group, and every CloudTrail trail logs these by default. Data events record data-plane operations on the resources themselves, an individual S3 GetObject or Lambda Invoke call, and are not logged by default; they have to be explicitly enabled per resource and typically cost extra given their much higher volume. This matters because an investigation into "who read this specific S3 object" will come up completely empty if only the default management events were ever being logged, a genuinely common gap discovered only during an actual incident.
What is a Service Control Policy (SCP), and what is the one thing it does not do?
An SCP is a policy attached to an AWS Organizations root, organizational unit, or member account that defines the maximum available permissions for every identity in that account, including that account's own administrators and its root user. What an SCP does not do is grant any permission by itself, it only sets a ceiling; an identity still needs an actual IAM allow (from an identity-based or resource-based policy) within that ceiling to do anything. An SCP with no matching IAM allow underneath it results in access denied, not access granted, which is the most common misunderstanding of how SCPs work. One exception worth knowing: SCPs never apply to the organization's management account itself, only to member accounts.
What does a container image scanner actually check, and how does it know an image is vulnerable?
A scanner builds a software bill of materials (SBOM) for the image, an inventory of every OS package and application dependency baked into its layers, then matches that inventory against a continuously updated vulnerability database. A match means a known CVE affects a specific version of a package present in the image; the scanner doesn't analyze the application's own logic, it identifies known-vulnerable versions of things the image happens to include, which is why keeping the dependency and base-image inventory small and current matters as much as running the scanner at all.
Why does explicitly telling a model it's allowed to say "I don't know" measurably reduce hallucination, and what's a second, complementary technique for the same problem?
Without that explicit permission, a model under an implicit expectation to always produce a confident, complete answer will sometimes fill a real information gap with a plausible-sounding but fabricated one; stating outright that uncertainty is an acceptable answer removes that pressure and lets the model surface "I don't have enough information" instead of guessing. A complementary technique for long documents is asking the model to first extract direct, word-for-word quotes relevant to the task before generating any analysis, grounding its response in verifiable text it actually has in front of it, and then citing which quote supports each claim, rather than generating an answer freely and hoping it stayed faithful to the source.
How does platform engineering differ from traditional DevOps or a shared infrastructure team?
Traditional DevOps distributes infrastructure responsibility to product teams ("you build it, you run it"), while a shared infrastructure team typically operates as a ticket-driven service, product teams request resources and wait. Platform engineering treats the internal platform itself as a product, with its own users (the engineers building on it) and a deliberate design goal: reduce cognitive load by providing paved, self-service paths for common needs, rather than either forcing every team to become infrastructure experts or making them wait on a queue. The platform team builds golden paths; product teams self-serve through them.