Git Rev News: Edition 130 (December 31st, 2025)

Welcome to the 130th edition of Git Rev News, a digest of all things Git. For our goals, the archives, the way we work, and how to contribute or to subscribe, see the Git Rev News page on git.github.io.

This edition covers what happened during the months of November and December 2025.

Discussions

Support

  • git-2.51.0: Fetching tags does not work

    Last September, David Bohman reported a regression in Git 2.51.0 where git fetch --tags failed to update tags in a bare repository. He noted that the command output indicated tags would be updated, but they were not actually added to the repository. Reverting to version 2.50.1 resolved the issue.

    Junio Hamano, the Git maintainer, attempted to reproduce the issue using a simple bare clone setup but was unsuccessful, suggesting that David needed to narrow down the specific conditions.

    In early November, David returned to the thread reporting that the issue persisted in Git 2.51.2. He provided a specific reproduction case involving a bare clone of the bind9 source repository. The output showed that one tag update was rejected (with a would clobber existing tag error), and consequently, all other valid new tags (v9.18.41, etc.) failed to appear in the repository, despite being listed as “new tag” in the output. The command exited with status code 1.

    Randall S. Becker suggested using git fetch --tags --force to clear the situation. David Bohman replied that while he could reproduce it locally, the key behavioral change was that prior to version 2.51, Git would fail regarding the conflicting tag but still insert the non-conflicting ones.

    Chris Torek identified the new reference transaction system introduced in recent versions as the root cause. He noted that the behavior had shifted to “all or nothing” (either all tags get updated, or none do) and questioned which behavior was actually buggy. David Bohman argued that this was a risky change for a mature tool and noted that the diagnostic messages were misleading because they reported success for tags that were not actually inserted.

    Karthik Nayak confirmed he could reproduce the issue and attributed it to transaction reference updates.

    Karthik submitted version 1 of a patch to fix the issue. He explained that commit 0e358de64a (fetch: use batched reference updates, 2025-05-19) introduced batched reference updates for git fetch. When fetching references, updates are added to a transaction. However, specifically when fetching tags, if a conflict occurs, the function fetch_and_consume_refs() returns an error code immediately. This caused the code to jump to the cleanup section, skipping the commit of the transaction entirely, and thus discarding even valid updates.

    The proposed fix involved extracting the transaction commit logic into a new function, commit_ref_transaction(), and ensuring it is called even when an error code is returned, provided the fetch is not atomic.

    Eric Sunshine reviewed the patch, asking why the test code was wrapped in subshells and suggesting that ! should be replaced with test_must_fail. Karthik agreed to these changes.

    Justin Tobler reviewed the code, agreeing with the logic. He suggested adding a comment to commit_ref_transaction() to distinguish it from ref_transaction_commit() and asked if the return value of this new function should be checked.

    Karthik submitted version 2 of the patch. This version added comments, removed subshells from tests, and extended the fix to the backfill_tags() function.

    Patrick Steinhardt reviewed version 2. He questioned the commit message’s mention of the deprecated “branches/” format in relation to tag backfilling. Karthik replied, clarifying that after re-reading the code, he understood that backfilling happens when the user does not specify --tags or --no-tags, confirming Patrick’s understanding.

    Patrick noted that the code now had three different call sites committing the transaction and felt it was “somewhat fragile.” Justin pointed out that the return code of commit_ref_transaction() was being ignored in the new implementation. Karthik agreed to check the return value.

    Karthik submitted version 3 of the series. He split the changes into two commits: one for extracting the logic and one for the fix. He also moved the commit logic into the cleanup section to avoid calling it at every failure point.

    Patrick reviewed version 3. He suggested using goto out in commit_ref_transaction() for better readability. He also asked for clarification on why the condition retcode > 0 was safe in the cleanup section, specifically regarding prune_refs(). Karthik replied, explaining that prune_refs() creates its own internal transaction, but later realized he was mistaken about the timing and promised to verify.

    Karthik submitted version 4. This version simplified the code and changed the check from retcode > 0 to just retcode.

    Patrick pointed out that the commit message regarding prune_refs() behavior change seemed incorrect because no transaction exists at that stage. Karthik verified this and confirmed there is no change for prune_refs().

    Karthik submitted version 5 with corrected commit messages and better test cleanup.

    Junio reviewed version 5 and identified a remaining issue. He noted that while the patch fixed the transaction commit, jumping to the cleanup label early meant that subsequent operations (specifically commit_fetch_head(), set_upstream(), and setting remote HEADs) were still being skipped when errors occurred. He argued that in non-atomic fetches, these should still run. Karthik agreed and proposed a fix to only jump to cleanup if --atomic was used.

    Karthik submitted version 6, adding a third commit to the series to address the skipped operations regression identified by Junio.

    Junio reviewed version 6. He liked the tests but warned against using touch to create files due to timestamp issues and noted a missing test case for --set-upstream on a successful fetch. Karthik agreed to fix these.

    Karthik submitted version 7, removing touch and adjusting the test prerequisites.

    Eric reviewed the tests in version 7, asking if ! test -f should be test_path_is_missing. Junio suggested using rm -f FETCH_HEAD before the test to ensure it is actually created during the run, and inspecting the file content to verify what was recorded. Karthik agreed.

    Karthik submitted version 8. This version verified the content of FETCH_HEAD and used test_path_is_missing.

    Junio commented that the series looked good. Patrick pointed out a tiny grammar nit (“eventhough”) and asked if the shell syntax >file used in the test was compatible with all systems, noting : >file is more typical. Karthik replied that existing tests use the shorter syntax, so it should be fine.

    The small patch series was eventually merged, and should be part of Git 2.53.0 that should be released at the latest towards the beginning of February 2026. With this version, not only the transaction logic will be fixed, but related regressions regarding post-fetch operations (like updating FETCH_HEAD) will also have been identified and resolved.

Developer Spotlight: Lucas Seiki Oshiro

  • Who are you and what do you do?

    My name is Lucas Oshiro, I’m one of the three GSoC ‘25 participants working on Git. I’m from São Paulo, Brazil, and I hold bachelor and master degrees in Computer Science from the University of São Paulo. I don’t have only one specific interest in programming topics, I enjoy several different topics, like lower-lever C code (like we do for Git), FP languages (especially Haskell), play with network simulators, data analysis, operating systems, databases and so on.

  • How did you initially become interested in contributing to Git, and what motivated you to choose it as your GSoC project?

    Well, it’s a long story… I think that it dates back to 2017, in a Computer Networks assignment at my university. My partner in that assignment was Matheus Tavares, who participated in GSoC ‘19 on Git. At the time, we needed to study a vulnerability and how it was fixed. We chose CVE-2017-1000117, which was a vulnerability in Git. That was my first time reading Git source code.

    Two years later, I was a member of a group focused on contributing to Free/Open-Source software at my University. I sent a patch to Git at the time, but I needed to focus on other stuff and I couldn’t finish it.

    After that, I started to work as a back-end software engineer and witnessed several Git-related problems. My two previous experiences with Git’s source code made me want to understand what was happening and delving into its internals, so I could help other developers from my company when something unexpected happened with Git.

    This way, Git always felt like the right choice.

  • How do you feel your contribution has impacted the Git community or the broader open source ecosystem?

    My GSoC project was to create the new command git repo info). It was released in Git 2.52.0 and, like many other new Git features, I expect it will take some time to be widely adopted, since it’s only available in bleeding-edge repositories. But I expect that it will be useful for forges, CIs, local tools, scripts, and other tools that depend on Git.

  • Is there any aspect of Git that you now see differently after having contributed to it?

    I can’t think of anything that I see differently after GSoC, but my previous contacts with Git’s source code made me realize the importance of having a good commit history with good commit messages. It also made me understand how powerful Git is as a debugging and searching tool.

  • How do you balance your contributions with other responsibilities like work or school?

    This year, I was more focused on finishing my master’s research and I didn’t have too many conflicts with GSoC, so I could focus on my master’s when my patches were under review. However, I must admit that one of the reasons that I didn’t apply to GSoC before was that, here in Brazil, we typically have final exams in June, which makes it hard to balance them with something else.

  • Can you share how GSoC helped enhance your technical and non-technical skills (like communication, project management, etc.)?

    I see Git as a product created by developers, for developers, and I think that here we sometimes need to do the work that in other contexts would be done by product owners and designers. I felt that especially during code reviews, which were often more focused on product and design decisions rather than the code itself. I had to learn how to discuss these kinds of decisions, always aiming to do what is best for Git and its users.

  • What was the biggest challenge you faced during your contributions to Git, and how did you overcome it?

    I think that the biggest challenge was the complete redesign of git repo info during the GSoC period, which made me re-write it from scratch several times. I think this was a consequence of my previous answer and that this challenge was solved itself.

  • Have you thought about mentoring new GSoC / Outreachy students?

    Yes, it would be very nice!

  • If you could get a team of expert developers to work full time on something in Git for a full year, what would it be?

    Git is amazing and I think we all agree that it makes the programmers’ lives easier. It would be great if we had a GUI wrapping Git but targeting non-technical users.

  • If you could remove something from Git without worrying about backwards compatibility, what would it be?

    Perhaps commands that accumulate responsibilities, like git checkout, git reset and git rev-parse. They make sense from the Git perspective, but I think they are confusing from the users’ perspective.

  • What upcoming features or changes in Git are you particularly excited about?

    Some that come to my mind are:

    • Patrick Steinhardt’s new git history command: rewriting history is essential to keep the repository sane and useful as a data storage, if done correctly. Currently we do that through interactive rebase but I think it can be intimidating for less experienced users. Jujutsu proposes a more straightforward way to do that, and it’s nice to see Patrick bringing it to Git.

    • Justin Tobler’s new git repo structure command: of course I’m interested in this subcommand since it is the sibling of my GSoC project. But it’s not only because of that: a Git repository is a very rich source of information and git repo structure will be a powerful tool to retrieve it.

    • Julia Evans’s contributions to documentation: Julia has been producing high-quality content about several programming topics for years. I’m happy to see Git being documented by someone so committed to spreading knowledge and who knows how to explain advanced concepts using a simple language.

  • What is your favorite Git-related tool/library, outside of Git itself?

    I use delta a lot, I like the way it highlights diffs. Other tools that I find interesting are Jujutsu and Magit, but I don’t use them too much.

  • What is your toolbox for interacting with the mailing list and for development of Git?

    I like desktop mail clients, but I don’t have a strong preference. On Linux, I use Thunderbird. On Mac, I use Apple Mail. I also have some GMail filters for classifying the messages (patches, What’s Cooking and Rev News announcements).

    However, those mail clients don’t have code syntax highlighting, and it’s hard to read the patches inside them. For that purpose, I use patch-hub, a TUI for reviewing patches from kernel mailing lists (including Git).

  • How do you envision your own involvement with Git or other open source projects in the future?

    There are some things I want to finish in git repo info, and I still send patches for it. I enjoyed contributing to Git and I don’t want to stop here.

    Outside Git development, I’ll give an advanced course on Git next month. It will be a great opportunity to share what I’ve learned here with other people.

  • What is your advice for people who want to start Git development? Where and how should they start?

    Read the Git Internals chapter from Pro Git, follow everything described in Hacking Git, and work on a microproject.

  • Would you recommend other students or contributors to participate in the GSoC, Outreachy or other mentoring programs, working on Git? Why? Do you have advice for them?

    Yes. I mean, I’ve already recommended some people from my university to apply to GSoC or Outreachy on Git and gave some tips to them. Some of them have already sent patches that were accepted.

Other News

Various

Light reading

Easy watching

Git tools and sites

  • check-projects is a fast, cross-platform CLI tool (with TUI interface) to check the Git status of multiple projects organized by categories. Written in Go, under MIT license.
  • repos is an interactive CLI tool for managing multiple Git repositories. Written in TypeScript (with pre-built binaries), under MIT license.
  • Patchy 🩹 is a CLI for generating and applying patches to Git repositories.
  • git-pw is a tool for integrating Git with Patchwork. Written in Python, under MIT license.
  • git-forge is a simple CLI tool for basic interactions with issues and pull requests across GitHub, GitLab, Gitea, and Forgejo. (Re)Written in Rust, under MIT license.
    See also git-forge: Faster Issues and PRs From Your Terminal blog post by Anh Tuan Le.
  • gtr - Git Worktree Runner by the CodeRabbit team is a portable, cross-platform CLI for managing Git worktrees with ease, with editor and AI tool integration. It automates per-branch worktree creation, configuration copying, dependency installation, and workspace setup. Written in Bash, under Apache 2.0 license.
    See also A Better Way to Run Git Worktrees Finally! by Julio Daniel Reyes on DEV.to, with video on YouTube [5:52].
  • Git Pow is an open-source, cross-platform Git client. It implements conditional strategies to handle larger repositories, showing image previews to visualize what changed, and grouping commits by month/year, among other features. Written in Rust and JavaScript using the Tauri framework. Under GNU GPL v3.0 license.
  • Git Repository Squirrel 🐿️ (reposquirrel) is a comprehensive Git repository analytics tool that provides detailed insights into developer contributions, subsystem ownership, and codebase evolution over time. Written in Python (using the Flask library) and JavaScript, under CC-BY-NC-SA 4.0 license. Demo and Docker image available.
  • Gitmal is a static page generator for Git repositories. Gitmal generates static HTML pages with files, commits, code highlighting, and Markdown rendering. Written in Go, under MIT license.
  • Git Rewind is a GitHub App that provides Your GitHub year in review — with privacy-first, read-only access (using fine-grained permissions). Written in TypeScript, under MIT license. Available at git-rewind.vercel.app.
  • Critic is a code review system. It is a web application written in Python, tightly integrated with Git. Under Apache 2.0 license.
    See also Meet Critic: Code Inspection System in Opera Software on Sudo Null IT News.
  • Buggy: Fast and simple bug tracker. The buggy program compiles a set of issues written in Markdown into HTML pages suitable to be read from a web browser. It is intended to be used alongside a version control system (VCS) like Git to track changes in the issues. Written in C, under MIT license.
  • Today I Learned: Git by Josh Branchaud, under MIT license.

Releases

Credits

This edition of Git Rev News was curated by Christian Couder <christian.couder@gmail.com>, Jakub Narębski <jnareb@gmail.com>, Markus Jansen <mja@jansen-preisler.de> and Kaartic Sivaraam <kaartic.sivaraam@gmail.com> with help from Lucas Seiki Oshiro and David Aguilar.