Skip to content

Mastering Git Rerere: Solving Repetitive Merge Conflicts with Ease

Mastering Git Rerere: Solving Repetitive Merge Conflicts with Ease

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Mastering Git Rerere: Solving Repetitive Merge Conflicts with Ease

Introduction:

Git, the popular version control system, has revolutionized how developers collaborate on projects. However, one common pain point in Git is repetitive merge conflicts. Fortunately, Git provides a powerful and not-so-well-known solution called git rerere (reuse recorded resolution) that can save you time and effort when resolving conflicts. In this blog post, we will explore how to configure and use git rerere, and demonstrate its effectiveness in solving merge conflicts.

Understanding Git Rerere:

Git rerere is a feature that allows Git to remember how you resolved a particular merge conflict in a particular file and automatically apply the same resolution in the future. It works by recording the conflict resolution in a hidden directory called .git/rr-cache. This way, when Git encounters the same conflict in the same file in the future, it can reuse the recorded resolution, saving you from manually resolving the conflict again.

Configuring Git Rerere:

Before using git rerere, you need to enable it in your Git configuration; only once git rerere has been enabled, Git will start recording and remembering resolved conflicts.Open your terminal and run the following command:

git config --global rerere.enabled true

This command enables git rerere globally, making it available for all your repositories. You can also enable it per-repository by omitting the --global flag.

How to use it:

Let's start with a really easy example, then describe a couple of use cases.

We have merged a branch (branch-one) into our main, and we are working on two different features in two different branches (branch-two and branch-three). We need to rebase our branches with main, so we start with

git checkout branch-two
git rebase main

It turns out that there are some conflicts on App.tsx file:

merge conflicts

We solve all the conflicts and finish with the rebase and push. As you can see, there are an extra line in the rebase output message that says:

git rebase

This means that thanks to rerere option enabled, we have saved in our project's .git/rr-cache this resolution for this particular conflict.

Now let's switch branches into branch-three cause we want to rebase on main also this one:

git checkout branch-three
git rebase main

It seems that we have the same conflicts here too, but this time, on the rebase output message, we can read:

merge conflict resolved

The conflict has been resolved automatically; if we check our IDE, we can see the change (and check if it works for us) ready to be committed and pushed with the same resolution we manually used in the past rebase.

merge conflict resolved

The example above focuses on a rebase, but of course, git rerere also works for conflicts that came out from a merge command.

Here are a couple of real-life scenarios where git rerere can save the day:

Frequent Integration of Feature Branches: Imagine you're working on a feature branch that frequently needs to be merged into the main development branch. Each time you merge, you encounter the same merge conflicts. With git rerere, you only need to resolve these conflicts once. After that, Git remembers the resolutions and automatically applies them in future merges, saving you from resolving the same conflicts repeatedly.

Reapplying Patches or Fixes: Let's say you have a situation where you need to apply the same set of changes or fixes to multiple branches. When you encounter conflicts during this process, git rerere can remember how you resolved them the first time. Then, when you apply the changes to other branches, Git can automatically reuse the recorded resolutions, sparing you from manually resolving the same conflicts repeatedly.

Benefits of Git Rerere:

Git rerere offers several benefits that make it a valuable tool for developers, regardless of whether you prefer git merge or git rebase:

  1. Time-saving: By reusing recorded resolutions, git rerere eliminates the need to manually resolve repetitive merge conflicts, saving you valuable time and effort.

  2. Consistency: Git rerere ensures consistent conflict resolutions across multiple merges or rebases, reducing the chances of introducing errors or inconsistencies.

  3. Improved productivity: With git rerere, you can focus on more critical tasks instead of getting stuck in repetitive conflict resolutions.

Conclusion:

Git rerere is a powerful feature that simplifies resolving repetitive merge conflicts. By enabling git rerere and recording conflict resolutions, you can save time, improve productivity, and ensure consistent conflict resolutions across your projects. Incorporate git rerere into your Git workflow, and say goodbye to the frustration of repetitive merge conflicts.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

"How do I undo my most recent commit?" - Mastering the git reset command cover image

"How do I undo my most recent commit?" - Mastering the git reset command

"How do I undo my most recent commit?" - Mastering the git reset command Git is a powerful version control system, but even experienced developers sometimes make mistakes. Whether you've committed changes to the wrong branch, made a typo in your commit message, or simply want to undo recent changes, the git reset command is your go-to solution. In this post, we'll explore how to use git reset to manage your commit history effectively. The Basics of git reset At its core, git reset moves the HEAD and current branch pointer to a specified commit, effectively "resetting" your working directory to a previous state. The basic syntax is: ` Where specifies how to handle changes in the working directory and staging area, and is the commit you want to reset to. Soft vs. Hard Reset: Understanding the Difference Git reset has two main modes: --soft and --hard. Let's explore each: Soft Reset (--soft) A soft reset moves your HEAD to the specified commit but keeps your changes staged. This is useful when you want to undo commits but keep the changes for recommitting. Example: ` This command undoes the last commit, keeping the changes staged. You can now make additional changes or recommit with a new message. Hard Reset (--hard) A hard reset is more drastic. It moves your HEAD to the specified commit and discards all changes after that commit. Example: ` This command undoes the last commit and discards all changes. Be cautious with this command, as it can lead to data loss! Specifying a Commit Hash Instead of using relative references like HEAD~1, you can specify an exact commit hash: ` This resets to the commit with hash 1a2b3c4, keeping changes staged. Using HEAD~n Notation The HEAD~n notation allows you to specify how many commits back you want to reset. For example: ` This resets to three commits before the current HEAD, discarding all changes. Reverting Pushed Changes If you've already pushed commits you want to undo, you should use git revert instead of git reset to avoid rewriting public history. However, if you must use git reset on a shared branch, you'll need to force push: ` Be extremely cautious with force pushing, as it can cause issues for other developers. Generic Usage of git reset git reset can also be used to unstage changes: ` This removes file.txt from the staging area without changing its contents. Conclusion The git reset command is a powerful tool for managing your Git history. Whether you're undoing recent commits, unstaging changes, or completely resetting your working directory, understanding the different modes of git reset can help you navigate tricky situations in your Git workflow. Remember to use git reset with caution, especially when working with shared repositories. When in doubt, create a backup branch before performing any reset operations....

Git Bisect: the Time Traveling Bug Finder cover image

Git Bisect: the Time Traveling Bug Finder

I think it’s safe to say that most of us have been in a situation where we pull down some changes from main and something breaks unexpectedly, or a bug got introduced in a recent deployment. It might not take long to narrow down which commit caused the issue if there’s only a couple of new commits, but if you’re a dozen or more commits behind, it can be a daunting task to determine which one caused it. But can’t I just check each commit until I find the culprit? You could just check each commit individually without any special tools until you find the one that caused the issue, but that can be a very slow process. This is not ideal and is analogous to the reason why linear search isn’t as effective as binary search. As the title suggests, there is a tool that Git provides called “bisect”. What this command does is checks out various commit refs in the tree of the branch you’re currently working in and allows you to mark commits as, “good”, “bad”, or “skip” (invalid / broken build). It does away with the need of having to check each commit individually as it is able to infer if commits are good or bad based on which other commits you have already marked. Git Bisect in Action Let’s imagine a hypothetical scenario where some bug was reported for the software we’re working on. Starting a git bisect session usually looks like the following example. ` In this case, the commit hash in this example comes from a commit that I already know works. In the case where you pull down changes, and only then does something break, you can use whatever commit you were at prior before you pulled them down. If it’s an older bug, then you could check an older tag or two to see if it exists there. Next is the part where we search for the offending commit. Every time you mark a commit, bisect will then navigate to another commit in-between your good and bad starting points using a specialized binary search algorithm. ` This is the general workflow you will follow when bisecting for its most basic use case, and these commands will be repeated until there are no more revisions left to review. Bisect will try to predict how many steps are left, and let you know every time you mark a commit. Once you are done, you will be checked into the commit that introduced the regression. This assumes that you marked everything accurately! After you are done bisecting, you can quickly return to where you started by running git bisect reset. How Git Bisect Works Firstly, bisect makes the reasonable assumption that any commits after a bad commit remain bad, and any commits before a good commit remain good. It then continues to narrow down which commit is the cause by asking you to check the middlemost commit, along with some added bias when navigating around invalid commits. Though, that’s not vitally important to understand as a user of the command. The following graphic shows how bisect moves throughout your branch’s history. Bisect becomes incredibly useful when dealing with repositories with a lot of history, or when tracking down the cause of a bug that’s been in a codebase for a long time. It makes it possible to mule over hundreds of commits in fewer than a dozen steps! That’s a lot better than going through commits one-by-one or at random. Limitations It is worth mentioning that bisect isn’t as useful in cases where commits are very large because they incorporate several different changes all bundled together (e.g. squash merges). In an ideal world, each commit in the main branch’s history can be built, and they will implement or fix one thing and one thing only. But in reality, this isn’t always the case. The skip command is available to help with this scenario, but even with that, it’s possible that a change that caused the bug is in one of those skipped commits; therefore, relying solely on the diff of the determined commit to find the root cause of a bug may be misleading. Conclusion Git bisect is a very useful tool that can dramatically decrease the amount of time it takes to identify the cause of a regression. I would also recommend reading the official documentation on git bisect as it’s actually quite informative! There are a lot of good examples in here that demonstrate how you can use the command to its full potential....

Introducing TanStack Query v5: A Leap Forward in Simplicity and Functionality cover image

Introducing TanStack Query v5: A Leap Forward in Simplicity and Functionality

TanStack Query v5: A Leap Forward in Simplicity and Functionality Introduction: Here at ThisDot we totally love TanStack Query, so we are really excited to share the news about the release of TanStack Query v5, the latest version of the powerful data-fetching library. The TanStack Query team has been hard at work, making significant improvements to enhance the library's usability and functionality. This blog post will explore the exciting new features and changes introduced in v5. Breaking Changes: One of the most notable changes in TanStack Query v5 is the removal of most overloads from the codebase. Previously, different overloads were used when calling useQuery and other hooks, resulting in inconsistent usage patterns and subpar TypeScript error messages. With the introduction of TypeScript 4.7, the team was able to unify the usage of these hooks, resulting in a more consistent and streamlined API. Now, developers only need to pass a single object, making the API more intuitive and developer-friendly. To assist with the transition, the team has updated the documentation, released an auto-fixable eslint rule, and provided a codemod tool. New Features: TanStack Query v5 introduces a range of exciting new features that enhance the data-fetching experience. Let's explore some of them: 1. Simplified Optimistic Updates: Performing optimistic updates is now easier than ever with the useMutation hook. Developers can leverage the returned variables without manually updating the cache. This streamlined approach simplifies the process and improves efficiency. 2. Sharable Mutation State: A highly requested feature, the useMutationState hook allows developers to access the state of all mutations across components. This shared state simplifies coordination and management of mutation-related data. ` 3. 1st Class Suspense Support: TanStack Query v5 fully supports suspense for data fetching. Hooks like useSuspenseQuery, useSuspenseInfiniteQuery, and useSuspenseQueries enable seamless integration of suspense in applications, providing a more efficient and intuitive way to handle data fetching. 4. Streaming with React Server Components: The new version introduces an experimental integration for suspense on the server in Next.js. By leveraging the react-query-next-experimental adapter, developers can initiate data fetching during server-side rendering (SSR) and stream the result to the client, combining interactivity and data synchronization. 5. Improved Infinite Queries: Infinite Queries now supports prefetching multiple pages simultaneously, allowing developers to optimize performance. Additionally, the maximum number of pages stored in the cache can be specified, providing more control over memory usage. ` 6. New Devtools: The Query devtools have been completely rewritten in a framework-agnostic manner, making them accessible to all adapters. With a revamped UI and new features like cache inline editing and light mode, developers can benefit from enhanced debugging capabilities. 7. Fine-Grained Persistence: Addressing a long-standing discussion, v5 introduces fine-grained persistence with the experimental_createPersister plugin. This plugin enables developers to persist queries individually, offering just-in-time restore capabilities, particularly beneficial for mobile development. 8. The queryOptions API: With the unified useQuery API, v5 introduces the queryOptions function, enabling type-safe sharing of query definitions between useQuery and imperative methods like queryClient.prefetchQuery. This enhancement improves code maintainability and type safety. ` Conclusion: TanStack Query v5 marks a significant milestone in the evolution of the data-fetching library. The breaking changes and new features introduced in this version enhance the developer experience, simplify usage, and open up exciting possibilities for data management. We encourage fellow developers to explore the migration guide, check the docs and leverage the examples provided to make the most of TanStack Query v5. Upgrade today and experience the future of data fetching with TanStack Query!...

Understanding Sourcemaps: From Development to Production cover image

Understanding Sourcemaps: From Development to Production

What Are Sourcemaps? Modern web development involves transforming your source code before deploying it. We minify JavaScript to reduce file sizes, bundle multiple files together, transpile TypeScript to JavaScript, and convert modern syntax into browser-compatible code. These optimizations are essential for performance, but they create a significant problem: the code running in production does not look like the original code you wrote. Here's a simple example. Your original code might look like this: ` After minification, it becomes something like this: ` Now imagine trying to debug an error in that minified code. Which line threw the exception? What was the value of variable d? This is where sourcemaps come in. A sourcemap is a JSON file that contains a mapping between your transformed code and your original source files. When you open browser DevTools, the browser reads these mappings and reconstructs your original code, allowing you to debug with variable names, comments, and proper formatting intact. How Sourcemaps Work When you build your application with tools like Webpack, Vite, or Rollup, they can generate sourcemap files alongside your production bundles. A minified file references its sourcemap using a special comment at the end: ` The sourcemap file itself contains a JSON structure with several key fields: ` The mappings field uses an encoding format called VLQ (Variable Length Quantity) to map each position in the minified code back to its original location. The browser's DevTools use this information to show you the original code while you're debugging. Types of Sourcemaps Build tools support several variations of sourcemaps, each with different trade-offs: Inline sourcemaps: The entire mapping is embedded directly in your JavaScript file as a base64 encoded data URL. This increases file size significantly but simplifies deployment during development. ` External sourcemaps: A separate .map file that's referenced by the JavaScript bundle. This is the most common approach, as it keeps your production bundles lean since sourcemaps are only downloaded when DevTools is open. Hidden sourcemaps: External sourcemap files without any reference in the JavaScript bundle. These are useful when you want sourcemaps available for error tracking services like Sentry, but don't want to expose them to end users. Why Sourcemaps During development, sourcemaps are absolutely critical. They will help avoid having to guess where errors occur, making debugging much easier. Most modern build tools enable sourcemaps by default in development mode. Sourcemaps in Production Should you ship sourcemaps to production? It depends. While security by making your code more difficult to read is not real security, there's a legitimate argument that exposing your source code makes it easier for attackers to understand your application's internals. Sourcemaps can reveal internal API endpoints and routing logic, business logic, and algorithmic implementations, code comments that might contain developer notes or TODO items. Anyone with basic developer tools can reconstruct your entire codebase when sourcemaps are publicly accessible. While the Apple leak contained no credentials or secrets, it did expose their component architecture and implementation patterns. Additionally, code comments can inadvertently contain internal URLs, developer names, or company-specific information that could potentially be exploited by attackers. But that’s not all of it. On the other hand, services like Sentry can provide much more actionable error reports when they have access to sourcemaps. So you can understand exactly where errors happened. If a customer reports an issue, being able to see the actual error with proper context makes diagnosis significantly faster. If your security depends on keeping your frontend code secret, you have bigger problems. Any determined attacker can reverse engineer minified JavaScript. It just takes more time. Sourcemaps are only downloaded when DevTools is open, so shipping them to production doesn't affect load times or performance for end users. How to manage sourcemaps in production You don't have to choose between no sourcemaps and publicly accessible ones. For example, you can restrict access to sourcemaps with server configuration. You can make .map accessible from specific IP addresses. Additionally, tools like Sentry allow you to upload sourcemaps during your build process without making them publicly accessible. Then configure your build to generate sourcemaps without the reference comment, or use hidden sourcemaps. Sentry gets the mapping information it needs, but end users can't access the files. Learning from Apple's Incident Apple's sourcemap incident is a valuable reminder that even the largest tech companies can make deployment oversights. But it also highlights something important: the presence of sourcemaps wasn't actually a security vulnerability. This can be achieved by following good security practices. Never include sensitive data in client code. Developers got an interesting look at how Apple structures its Svelte codebase. The lesson is that you must be intentional about your deployment configuration. If you're going to include sourcemaps in production, make that decision deliberately after considering the trade-offs. And if you decide against using public sourcemaps, verify that your build process actually removes them. In this case, the public repo was quickly removed after Apple filed a DMCA takedown. (https://github.com/github/dmca/blob/master/2025/11/2025-11-05-apple.md) Making the Right Choice So what should you do with sourcemaps in your projects? For development: Always enable them. Use fast options, such as eval-source-map in Webpack or the default configuration in Vite. The debugging benefits far outweigh any downsides. For production: Consider your specific situation. But most importantly, make sure your sourcemaps don't accidentally expose secrets. Review your build output, check for hardcoded credentials, and ensure sensitive configurations stay on the backend where they belong. Conclusion Sourcemaps are powerful development tools that bridge the gap between the optimized code your users download and the readable code you write. They're essential for debugging and make error tracking more effective. The question of whether to include them in production doesn't have a unique answer. Whatever you decide, make it a deliberate choice. Review your build configuration. Verify that sourcemaps are handled the way you expect. And remember that proper frontend security doesn't come from hiding your code. Useful Resources * Source map specification - https://tc39.es/ecma426/ * What are sourcemaps - https://web.dev/articles/source-maps * VLQ implementation - https://github.com/Rich-Harris/vlq * Sentry sourcemaps - https://docs.sentry.io/platforms/javascript/sourcemaps/ * Apple DMCA takedown - https://github.com/github/dmca/blob/master/2025/11/2025-11-05-apple.md...

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co