Hacker News new | past | comments | ask | show | jobs | submit login
Highlights from Git 2.35 (github.blog)
258 points by ossusermivami 6 months ago | hide | past | favorite | 88 comments

Finally there is `git stash --staged` and I can stop making temporary commits which I might forget about later and accidentially push.

Woah, it didn't already? Magit has made that easy forever and I just assumed it was part of git at this point.

Hah, I was thinking the same thing and jumped to comments to see if someone else mentioned it. I actually use this quite a bit in Magit.

Magit is genuinely amazing.

Thanks @tarsius!

I usually try to leave the Magit praising to others in these threads but in this case I would have found it hard to resist. Glad others have already taken care of it. ;P

You've made a thing that has many loyal users, myself included. :)

Will this change make your work on Magit easier?

If there was something you could add/remove to/from Git to make your life easier, what would it be?

It probably doesn't make much of a difference because Magit's stashing commands offer more flexibility that even after this addition is still missing from `git stash`. Stash creation is actually one of the very few areas where Magit doesn't use the respective Git procelain commands at all (as opposed to using them and then doing additional things using other pluming and/or porcelain commands as is the case in many other areas).

Also I have to continue supporting older Git releases anyway; people like to use the latest Magit version without considering doing the same for Git, for some reason.

Change the license to GPLv2 OR later.

+1. Magit is definitely the best Git client out there. It makes even non-standard functions transparent to the user.

I really want those temporary commits to end up part of the finished git history, but be hidden from most views... for example, they could be called "sub commits", and tools could not show them by default unless given some extra flag. Then there could be sub-sub commits, etc to show more and more minor edits, potentially down to individual keystrokes.

Throwing away the construction history of something just seems wrong in git-land. The git format already allows this - it's just the tooling and culture that needs to be adapted for it to happen.

Maybe the culture of easy to understand commits exists for a reason?

Imagine someone sending in a patch for the Linux kernel, or for git itself, only it isn't only the patch but a bunch of temporary patches that in the end forms something usable. (But don't worry because a git feature will make the log skip over it!) Would you really want to review that? Would you really want it stored in the repository for all eternity?

Crafting commits that are easy to understand and gives enough context to understand the change is the only way a large software repository can survive without collapsing under its own historical weight.

Thanks, gonna steal using the Linux kernel development as an example regarding this matter. Probably also any huge-scale repo like Google or Windows would work, but Linux is awesome because open source.

I'm honestly rather confused on the whole idea of valuing the journey instead of the end result. Aren't commit messages literally the built-in way to write about your journey to your heart's content? And failing that, you probably (should) have a ticket system or the like to preserve even more context in the form of third party comments etc.

I usually compare git history to a book: it's not valuable for the end user to see all the tiny edits and errors the author made before the final version, and in the end the important thing is that it tells a good story that the end user can easily follow.

Like it's said, the source code is for us humans to read. The computers would do just as fine without the story its trying to tell.

Removing or glossing over can always be done later.

Adding back the thought process that the commits can reveal can often be hard later, even for the original author.

Removing can't always be done later, because that requires rewriting the repository's history.

Logical commits serve a real purpose: they make change review easier and can help bisect bugs later.

That's orders of magnitude more useful than someone else's development thought process, which may or may not even make sense to anybody else.

If thought process is important, it should be captured in a structured way like a thoughtful commit message or README addition. Not some cobbled together mess of whatever commits someone made haphazardly.

First: are we talking past each others? You seem reasonable but some of the things doesn't make sense to me which often indicates a misunderstanding on one of the sides :-)

If not, here are some clarifications. (Maybe they'll help even if we are talking past each other.)

> Removing can't always be done later, because that requires rewriting the repository's history.

I knew this could come up which is why I included glossed over.

> Logical commits serve a real purpose: they make change review easier and can help bisect bugs later.

Nothing I wrote was meant to conflict with that. Quite on the contrary I specifically want more points to bisect against (yes, I'm one of those who actually uses bisect).

> If thought process is important, it should be captured in a structured way like a thoughtful commit message or README addition. Not some cobbled together mess of whatever commits someone made haphazardly.

Have you tried getting anything reasonable about the thought process behind a feature into a README, and then tried to get it to stick there?

On the other hand a bunchbof commits along the lines of:

- rough first sketch

- introduce tests.

Also includes modifications to xyz to simplify testing.

- performance optimizations

- more tests

- Introduce test for foo and fix it in bar and baz

This has a negative impact on performance but is hard to avoid.


Could you please elaborate on the value you find in commits from other people that are along the lines of "more tests" or "first sketch", as opposed to crafting a coherent single commit with a thoughtful commit message?

I'm honestly asking in good faith, as the commits you gave as an example are literal anathema to me, and I'd like to understand what value anyone can see in them.

The one I value is the "performance optimizations" and the last one.

Problem is if we let squash zealots have their way they are gone together with the rest.

Storage is cheap.

You'll never ever be bothered by those commits unless you are bisecting and at that point you are probably thankful of you can find a commit message along the lines of:

- performance optimizations

- workaround for weird problem foo problem in prod

as they will tell you a lot about how to approach it.


Just having tests and modification because of tests added in their own commit and with a comment ("Also includes modifications to xyz to simplify testing." above) is useful.

I do look into commits on a weekly basis or more to figure out why stuff was moved / replaced.

Just yesterday I stopped a PR because a constant was changed in an unrelated commit as part of the larger PR.

Because commits are granular it was really easy to see that it wasn't intended.

> I specifically want more points to bisect against (yes, I'm one of those who actually uses bisect).

Wouldn’t that make bisecting more difficult?

If your history is full of checkpoint commits, wouldn’t bisect send you to broken commits (that you’d have to `--skip`) more often?

Why would you want to deal with those extra steps?

Just make sure every step make sense. One or even two or three extra bisect steps is nothing in my kind of projects as long as you get a very specific change.

I guess on AAA game engines where compiles take half an hour it is more of a problem but in my case it takes 30 - 120 seconds depending on project.

(I do have uncompilable WIP steps, and those I am kind of ashamed for but those are so few and so far between that it doesn't matter.)

This sort of happens naturally with a branch-and-merge workflow. The merge commits are what matter. With bors the merge commits get tested before merge and get their commit messages populated from the PR description.

What's missing is many git tools don't let you easily filter out non-merge commits.

Given git's support for merge trees, and arbitrary workflows, this already exists, it's just hard to access. With git, you can create a commit history that looks like this:

    | B
and git log --first-parent will show A and C, and hide B, even though B's code is contained in A. We used this all the time at Ksplice, where we had some custom tooling that made it easy create those triangles and our build system would use the commit message on A while ignoring B in order to build updates.

What do you have in mind? Always hiding second parents of second parents? Or a special marker in G's commit message?

I feel the same, except I'd want only me (as the author/committer) to be able to see my sub-commits :D

This feeling goes away the senior you get.

What is the point of keeping construction history? How far do you go? Install a keylogger on each developer's machine?

I'd love to be able to stash individual bits of a diff (from magit) to do something like bisecting on the current changes.

Something like how the current `add -p` allows you to select or reject any given chunk.

Doesn't git stash save -p accomplish that?

The way to get a correct answer on the internet:

  1) Post the wrong answer.
  2) Get corrected.
  3) Profit

Cunningham's Law! "the best way to get the right answer on the internet is not to ask a question; it's to post the wrong answer."

> But what if you only want to store part of your changes in the stash? You could use git stash -p and interactively select hunks to stash or keep.

It's even right in the article. (Then goes on to describe how this change means you can stash those chunks easily if you've already selectively staged them.)

Is this any different than soft reset then git stash

Presumably it doesn't include unstaged changes in the stash.

Yes, --staged doesn't include unstaged changes.

Switching the diff algorithm to histogram is really useful when staging things selectively (via 'git add -p', Magit status buffer, etc.).

For example, if we've inserted ABC and removed XYZ, we might want to put those in separate commits: insert ABC above XYZ, then remove XYZ. If the diff gets them the wrong way round (inserting ABC below XYZ), then we have to manually edit the patch.

This is unavoidable in general, but fiddling with the options can reduce its occurrence. In particular, the default algorithm often spots exact matches like lines only containing '{', then comes up with really convoluted diffs in order to keep those braces matched up (often this will delete entire functions and add them all back!).

Thank you. I use interactive staging all the time with Magit so this might make a difference for my workflow.

For anyone not using `merge.conflictStyle = diff3` I highly recommend trying it. It removes a lot of ambiguity when dealing with conflicting changes.

And now they introduced `zdiff3` which looks even better, will be trying it once I update.

> For anyone not using `merge.conflictStyle = diff3` I highly recommend trying it. It removes a lot of ambiguity when dealing with conflicting changes.

Yes, and to say that another way, it's literally impossible to resolve merge conflicts correctly with only the standard conflict style. See my post on StackOverflow for more details: https://stackoverflow.com/a/63739655/997606

I use kdiff3 or bc4. I find those tools more powerful for fixing complicated merges and just as easy for simple ones (eg manual alignment for when the merge algorithm can’t recognize what is supposed to be aligned)

I’ve tripped over the exact scenario you mention in that post more than once. Usually, it’s not that I end up including an entire function that shouldn’t be there, though. I find it tends to be more like “Oh, here’s an extraneous bit of code that just showed up in the middle of this method. Hmmm....” Or, alternatively, I end up removing too much code, rather than too little.

(plug) delta does special display of diff3 merge conflicts: https://github.com/dandavison/delta#merge-conflicts

It displays two diffs: one from the ancestral commit to “ours” and one from the ancestral commit to “theirs”. I find it helpful for understanding conflicts and how to resolve them — any feedback appreciated.

Yessssssssss! zdiff3 was by far the most exciting thing in the whole announcement for me. It’s a terrible feeling that comes over me when, not only do I get the pleasure of resolving a merge conflict, but I do it incorrectly, leading to a bad merge. Minimizing the amount of lines I have to consider when doing so seems like the most straightforward way to increase the accuracy of humans when resolving merge conflicts.

I wonder why they introduced new diff mode, rather than making diff3 better.

It's semantically slightly different. In the case of diff3 if you remove everything but the base part, then you get exactly the base version, while in the case of zdiff3 you also get the prefix and suffix parts from the two branches that merge cleanly.

I guess the difference is subtle, especially that there can be other merges within the same file that merge cleanly in both cases.

Some people are used it, prefer it and probably it would break some automated tests people have too.

who cares?

I hate this approach because this is very lazy (you avoid thinking about hard stuff and pick easy solution) and is very short term

sure you can introduce 150 configuration modes

but it makes your thing messy, confusing for new people, confusing for inexperienced and requires more maintenance

it's like taking tech debt

> who cares?

Loads of people who have to maintain things.

This is a standard approach to software development: you introduce a new alternative for something that exists, then mark the existing inferior option as "deprecated". This gives developers a chance to learn about the new feature and move over to it by the time it actually gets removed in a future version. Cutting it immediately would cause a huge amount of frustration since the users of the feature would demand to know where it went or why it suddenly no longer works while the maintainers would have to scramble to find a solution. It would turn people off from using that software in the future.

The thing is that

>by the time it actually gets removed in a future version.

doesn't always happen, so we're left with new, new v2, new v3 options and old one still exists "because it may break somebody's workflow"

I would argue that for most cases, that's preferable to simply cutting old functionality. The only exception would be in environments where the upgrade process is more rigid where users/admins know what's changing with an upgrade and have a safe and easy way to roll back in case of any issues.

The SSH signing feature is interesting as it can reduce the number of secrets I'm managing.

Is my understanding correct that you'll also need the git hosting providers (Github, Gitlab) to understand and interpret those kinds of signed commits in order to show the 'verified' badge?

In the official feedback discussions [1] from December 2021, the answer for this question was "won't start working on it for 2-4 months".

[1]: https://github.com/github/feedback/discussions/7744#discussi...

that's correct it's not currently supported on these platforms.

Does anyone know what the status is of the transition from SHA-1 to SHA-256?

Still considered experimental in 2.35.0: https://git-scm.com/docs/git-init

Git jump is interesting, not new in this release (in 2.19) but I wasn't aware of it. I'm generally already in vim in another shell though, so I want the quickfix list populated there, not in a new instance.

A while ago I wrote a vim plugin for this, has a bug where it (only sometimes?) won't go to the last conflict, but it's been helpful enough that I use it frequently.


(Yes, shameless promotion/maybe bait someone more familiar with vimscript into using it and immediately spotting cause of the above!)

TIL there is a `--histogram` diff mode, producing more readable diffs.

TIL the reason Windows and Linux `long` are different is called "64-bit data model".

If you want to learn more about it:

- The reason the Unix world chose to have "long" as 64 bits: https://unix.org/version2/whatsnew/lp64_wp.html

- The reason the Windows world chose to keep "long" as 32 bits: https://devblogs.microsoft.com/oldnewthing/20050131-00/?p=36...

It's fascinating. Win chose LLP64 because pinned LONG to 32bit width in various format headers.

Good grief git is big.

If you are interested in a code review of git architecture: https://fabiensanglard.net/git_code_review/index.php

Yeah, I was hoping some expert architects like Martin Fowler would provide blueprint of next generation Micro service architecture for git.

Not sure if you're joking or not ^^.

Am I the only one whose mind is blown that there is no official download I can click to install on Mac?


I tried brew and it seems to have the old version; another download link gives me a 5-month-old version. Why is there no official click-to-install release?

It was updated in homebrew yesterday[1]. Your homebrew package index is probably just out of date. Run `brew update` to update all formulae.

  11:15:43 ~  brew info git
  git: stable 2.35.0 (bottled), HEAD
  Distributed revision control system
  /usr/local/Cellar/git/2.34.1 (1,513 files, 42.7MB) *
  Poured from bottle on 2021-11-30 at 14:52:55
  From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/git.rb
  License: GPL-2.0-only
[1]: https://github.com/Homebrew/homebrew-core/blob/master/Formul...

    brew edit git
That should open this in your editor:


Change the url and sha256, then

    brew install git
(This is from memory; I'm not in front of a shell, but I think it's correct.)

The mac version doesn't have enough volunteers?

Is it only me or is git terribly complicated? How is average Joe (or rather: average coder) supposed to handle it correctly?

It’s not just you. Git is complicated.

Some of the complexity is because of some bad UX decisions that were made early on. Those are difficult to undo.

I’d recommend an average coder to practice, be patient, and not give up. I don’t think there’s a way around it. They’ll eventually get the hang of it, form a decent mental model, and eventually master the subcommands and switches they find most useful.

What is your problem?

Anybody know if it’s possible to run a formater before diffing? For example running “go fmt” or “prettier”?

I haven't tested this, but maybe it will serve you as a starting point.

Throw this script into $PATH (let's say into ~/.local/bin/diff-fmt):

  exec delta <(gofmt "$1") <(gofmt "$2")
here I'm using delta as the difftool: https://github.com/dandavison/delta

and then, once:

  $ git config --global interactive.diffFilter diff-fmt

Thank you, will try it out :-)

Wouldn't it be better to do that before committing? Or by using a hook?

Since diff is used to make patches it could ruin things I imagine..

Yes, using a hook is optimal. But when reading repos without a style guide or formater, “pretty diffing” makes it easier to review.

Another use case is when you encounter that giga god-commit “added formater” which touched all lines in all files.

If you take this even further, you can tailor to anyones style taste, formatting on check out instead of check in. That leaves the stored code as a serialization format the compiler understands. Viewed code is in whatever format the programmer likes.

Am I the only one not seeing a `git jump` command in v2.35.0 installed via brew?

it's an extra script to install

i love that github does this

Any reasons (beyond PR) that these highlights are posted on the blog of GitHub instead of on the main website of Git itself?

Sadly, even Google is so confused about Git VS GitHub that searching for "git blog" shows github.blog as the first result...

>Any reasons (beyond PR) that these highlights are posted on the blog of GitHub instead of on the main website of Git itself?

Probably the most obvious reason is that author Taylor Blau is employed by Github. If Github funds his work on Git, it doesn't seem strange at all that he posts on his employer's website.

Also, if you're referring to "git-scm.com" as the "main website of Git", there may be practical reasons such as TB not having any authoring privileges there to write a blog type of post. I notice that Git contributor Junio C Hamano who wrote the Git release notes doesn't post blog articles there either. JCH's blog-style posts seem to be at a different url: https://git-blame.blogspot.com/

You didn't ask but a related question people wonder about is why HN users (such as ossusermivami in this thread's case) submit Github links more often than the Git mailing list release notes: https://news.ycombinator.com/item?id=28207811

> but a related question people wonder about is why HN users (such as ossusermivami in this thread's case) submit Github links more often than the Git mailing list release notes:

I'd wager because it's more discoverable, more readable and contains very useful layman-readable explanations of what is going on in this release

that's correct :) It's much easier to follow by RSS the GH blogs than following the ML. And even if I was following it, it's not very trivial to find the mailing list archive html url (and I use Gnus to read mailing list)

Because this is a blog post by GitHub about the new release of Git, not in any way associated with the Git project.

The Git project itself posts release notes, but those are more abbreviated and aimed at a audience that's a bit more familiar with Git's workings: https://raw.githubusercontent.com/git/git/master/Documentati...

Because they are written by a GitHub employee. If there were equivalent posts on the Git website, one could argue that we should link to those instead, but it is GitHub who writes and publish these posts and even if they are a form of PR, they are informative nevertheless.

That's what happens when the github blog consistently puts out better content than the git blog.

> Sadly, even Google is so confused about Git VS GitHub that searching for "git blog" shows github.blog as the first result...

Does https://git-scm.com/ even have a blog? I don't think Google is confused, it's just trying to give you the most relevant results.

These threads always have a comment about the Git/Github distinction.

You seem a bit confused yourself. GitHub and Git are different entities. So this is like asking why the New York Times is commenting on the price of tea in China—why shouldn’t they comment on it?

If you want the news straight from the source (without nice HTML markup): https://marc.info/?l=git&m=164305383314846&w=2

Same reason as every other time such a post has elicited such a “this is a PR stunt by GitHub” comment.

Obviously because GitHub (i.e. Microsoft) wants to pretend that they are the Git project, with all the goodwill that entails. Most people already think that Git and GitHub are the same, so it only takes little things like this to reinforce it over time.

Applications are open for YC Winter 2023

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact