Bootcamps

Structured programs that take you from the fundamentals to deployment. Hands-on, mentor-led and built around real projects.

Learn it all the way down

400+ hours of structured learning, real-world projects, mentors from the field and 200+ AI study assistants around the clock.

Bootcamps Featured

    The heavyweights
      Why these

      Pricing

      Flexible plans designed for every learner — from free trials to enterprise solutions. Invest in your future with transparent, value-driven pricing.

      Start learning for free

      Every course offers free trial access. Upgrade to a membership for unlimited learning, or explore our bootcamp and enterprise solutions for structured, mentor-led programs.

      Pricing Featured

      About

      Democratizing AI education for over 1 million learners worldwide. Built by engineers, researchers, and educators who believe in limitless potential.

      Our story

      Behind everything great that someone builds is the moment it finally made sense. We started Lunartech to give you more of those moments.

      About Featured

      Learning Version Control Properly

      Git feels like a list of commands until a mistake makes its model clear. Learning the model first makes the commands easier to remember.

      LUNARTECH AcademyNov 5, 20264 min read

      On this page
      1. The model: commits, branches and history
      2. A practice repository you can break
      3. Recovering from mistakes
      4. Commit messages as a record
      5. When to avoid rewriting history
      6. A practice session to finish

      Git feels like a list of commands until a mistake makes its model visible. Once the model is clear, the commands become predictable, and most of what seemed risky becomes a matter of moving labels within a history. The model is simple: a project's history is a graph of snapshots, and branches are movable names that point into that graph. Learn that first, and the commands follow.

      The model: commits, branches and history

      Each commit is a snapshot of the project plus a link to the commit before it. The history is the chain of these snapshots. A branch is a label that points to one commit, and it moves forward when a new commit is made while that branch is checked out. A special pointer, usually called HEAD, records which branch is current. Most everyday commands either add a commit, move a label, or change which label HEAD points to.

      Take a concrete case. The branch named main points to commit C. A change is committed as D, whose parent is C. Now main points to D, and nothing else in the history changed. Once every ordinary operation is seen as a small move of this kind, the commands stop being separate facts to memorize.

      There is one more place a change can sit before it becomes a commit. The staging area holds the changes chosen for the next commit, and it lets you commit part of a file rather than all of it. Many confusions come from forgetting that this middle step exists. A change that is not staged will not appear in the commit, however carefully the message was written.

      A practice repository you can break

      Create a throwaway repository in a scratch folder, outside any real project. Make three commits on purpose, each changing one file. Create a branch, change the same line on both branches, and merge to produce a conflict. Resolve the conflict by hand and commit the result. Each step is cheap to repeat, and mistakes cost nothing.

      The throwaway matters because practicing in a shared repository risks history that other people depend on. Local experiments are safe. Pushing to a shared branch is where mistakes begin to affect others.

      Look at the history often while practicing. A compact one-line view of the log, or a tool that draws the branches, shows the graph you are describing in words. Matching the picture to the commands you just ran is one of the fastest ways to build the model.

      Recovering from mistakes

      Most lost work in Git can be recovered for some time, because the reflog records recent movements of HEAD and branches, not only the commits themselves. If a branch is reset or deleted by accident, the commit usually still exists and can be found there. The first step is to stop and look. Reading the status and the log before acting prevents most damage. A typical recovery looks like this:

      git reflog
      git switch -c recovered-work HASH

      The reflog lists entries with identifiers, and HASH in the example stands for the one you choose. Pick the one from just before the mistake, and create a branch pointing to it. Check the contents before merging anything back. The reflog is local and expires eventually, so recovery is most reliable when it happens soon after the mistake.

      Commit messages as a record

      A commit message should state what changed and why. The first line is a short summary that reads well in a list of history. The body explains the reason, including rejected alternatives when that is not clear from the code.

      A message such as "fix bug" records almost nothing. "Stop the parser dropping quoted commas, found while importing the vendor file" tells a future reader what broke, where it was found and why the change looks the way it does. Future readers, including the author, reconstruct intent from history, and the message is often the only place the reason is stored.

      A useful check is to finish the sentence "this change will" with the message's summary. If the sentence reads awkwardly, the commit probably contains two unrelated changes and should be split.

      When to avoid rewriting history

      Some commands rewrite history. They produce new commits with different identifiers and leave the old ones behind. Rewriting unshared commits to tidy them before review is ordinary and safe. Rewriting commits that others have already fetched is different. Their copies no longer match, and the next update produces confusion or duplicated work.

      The trade-off is between a clean history and shared safety. The check is simple: has anyone else fetched this branch? If so, add a new commit instead of rewriting, and accept a less tidy history in exchange for a stable one.

      Merging and rebasing are two ways to bring work together, and they leave different histories. Merging keeps each branch as it was and adds a join. Rebasing replays commits on top of a new base. The choice matters less than consistency within a team, and than knowing which one a given branch used.

      A practice session to finish

      Spend about half an hour in the throwaway repository. Make three commits, deliberately delete a file in the last one, and recover that file from the reflog rather than from a copy. Create a branch, make a conflicting change on it, and resolve the conflict. Write a message for each commit that states the change and its reason. Then explain, without the screen, what each command did to the labels and the graph. If you can do that, unfamiliar commands will be easier to reason about. If you cannot, repeat the exercise with the graph drawn on paper after each step.

      More from Dimension

      View category

      Reading is the start.Build it next.

      Structured bootcamps and courses, from the mathematics up to production.