Highlights from Git 2.28
github.blog
github.blog
I don't follow each Git release, but I also didn't notice a great productivity enhancement for a long time. Sure it is a sign of a mature project, but I'd like to know:
What's the somewhat recent Git feature that you really improved your productivity?
It's not just better name for doing "git checkout -- path". "git checkout" has this stupid behavior of restoring files to worktree and index. "git restore" by default doesn't touch index (I wrote SO answer that explains this a bit more: https://stackoverflow.com/a/60855504/350384)
there is also "git switch" but I just kept using "git checkout" because there is nothing "git switch" can do that "git checkout" can (it's just a shorter name but I had aliased "checkout" to "ch" anyway, as many people do)
It pays to follow the release notes because some of these features are opt-in (e.g. commit graph is still optional).
The sparse checkout stuff is great but still too low-level for us to use, but it's laying the groundwork for something good.
It's not at all new according to a quick grep of RelNotes, but I only recently discovered it, so it is new to me.
Those confusing switches are already ingrained in my memory (or hidden away behind aliases) and now I find it more confusing that git is recommending new and different commands to do things that I've been doing a fixed way for years.
`git restore <file>` instead of `git checkout -- <file>`is another one.
git restore and git switch basically tries to seperate the functionality.
i.e. from: "git-checkout - Switch branches or restore working tree files"
to
- "git-switch - Switch branches"
- "git-restore - Restore working tree files"
tbf I found it really stupid from the beginning that it tries two things at once.
Godsend if you regularly need to work on multiple branches simultaneously.
git range-diff
Very useful to get an overview of what changed after a rebase.Or maybe not: I guess it's kinda slow and heavy on computation.
This makes git diff highlight reindented or moved lines differently.
I use it to get diffs similar to when you pass -w, but with a bit more context.
It takes a bit of experimenting to keep it from looking like a fruit salad, but sometimes you get interesting results.
https://git-scm.com/docs/git-diff#Documentation/git-diff.txt...
It speeds up git status on large codebases
https://github.com/git/git/blob/master/templates/hooks--fsmo...
Its not easy to set up git config settings for a distributed team. I assume for security reasons a repo can't configure its own settings just from a pull but even still I want that functionality.
Why do I check in the name of the merge tool used for a file type in the .gitattributes but I can't check in what that name points to?
I work with less technical artists and they really don't want to think about git configs at all. They just want to save and push. As far as I know there's no solution to preconfigure a repo to pull submodules or set up custom merge drivers. Best thing I've found is to maintain repo setup scripts but its pretty cumbersome and you have to manually target the tools you want to support.
Is there a way to request this sort of stuff or a place to look at roadmaps without getting into the whole mailing list scene?
Maybe this sort of thing should be the responsibility of github/gitlab and not git itself?
Highly recommend this.
And as far as "pages of instructions in various states of decay," couldn't agree more that those aren't a good solution. I usually observe those instructions containing lots of terminal commands. I'd rather have those in an executable format, with commenting if explanation is needed. Then it's (usually, hopefully) pretty obvious where something breaks, instead of rotting instructions nobody can say 100% what is or isn't current.
Example:
git-setup.out: touch $@
I just can't help but feel like if this is the common pattern, then it should be built into one of these tools in a more consistent way.
[1]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
Git settings can do a lot, including running arbitrary commands. Having this set up automatically is a massive security issue. Put a script in your repo somewhere and instruct people to run the script after cloning.
> Why do I check in the name of the merge tool used for a file type in the .gitattributes but I can't check in what that name points to?
Because the configuration may be different from machine to machine. For example, one machine might have git-lfs installed in /usr/local/bin, another in $HOME/.nix-profile/bin/git-lfs. Similarly, the actual filters may be set up differently from machine to machine, e.g. one person might use `git lfs install` (to install globally) and another `git lfs install --skip-smudge --local` (to install locally to this repo, configured to skip fetching unknown objects on clone or pull).
> I work with less technical artists and they really don't want to think about git configs at all. They just want to save and push. As far as I know there's no solution to preconfigure a repo to pull submodules or set up custom merge drivers. Best thing I've found is to maintain repo setup scripts but its pretty cumbersome and you have to manually target the tools you want to support.
Skimming config right now, I do see a `submodule.recurse` flag which, if set, causes any command except `clone` that has --recurse-submodules to automatically recurse.
The aforementioned setup script could set this config flag and run `git submodule update --init -recursive` to clone the submodules too in case the user didn't pass --recurse-submodules to `git clone`.
This is the crux of the issue. I want something to ensure turn-key configuration in a secure and cross platform way.
Maybe github/gitlab could generate something like an installer script instead of just a clone url.
One such package manager can be npm (if you use Node anyway), it can install and run scripts.
But having to run a setup script once could be massively simpler, though less flexible.
Git itself is not the right place to have it because of the security issues with it, but if you can run Ansible or something similar then you have root on the system anyway.
Nice to see efforts to reduce barriers to contributing.
1. I do `git log` which helpfully pipes to `more` where I can use vim-stsyle search to find the commit I'm interested in. 2. I find the relevant commit. 3. Now I want to `git show` that commit.
Currently I double click on the human unreadable commit, copy it, quit `more` to get back to the command line, type `git show`, then paste the commit. Navigate, click-click, shortcut, 'q', type a command, paste. That's six pieces of business.
That seems very wrong and time-consuming.
How do I go gracefully from browsing git log to git show without retyping/pasting the human unreadable commit? Preferably with fewer than seven steps.
I personally use magit, which solves this problem across all of git, but it's tied to Emacs.
tig is a git log browser I've heard good things about that seems to handle this use case very nicely.
You may also be able to pervert less into making this easier, e.g. by using lesskey(1) to add a keybinding that runs `git show $(xclip -o)`. I don't know how wise that would be.
For what I see, magit is way ahead when it comes to the feature set, but tig has the killer feature of having a completely flat learning curve (and I say this as an Emacs user): 1) type tig 2) use arrows to move between commits and page up/down to move within diffs. That's all!
To navigate efficiently between the commits, you could pre-seed less with a regex that matches commit (and file) lines, so that "n" and "N" jump from one commit (or file) to the next, something like this
LESS="-R --pattern ^(commit|diff) " git log -p
Delta[1] makes this convenient: delta --navigate.[1] https://github.com/dandavison/delta
(Disclosure: I am the author of delta)
There are just so many things in the git CLI that are a single step away from being usable by default. For example, in Gitlab by default you see a tag to let you know if a branch has been merged. I can do the same in cli by exploring my flag options, but that time adds up for every little convenience that happens to be missing. (And as Gitlab shows, it's not impossible to choose a set of default conveniences that cover the bases for an enormous percentage of the users.)
I'll definitely look into that jumping pattern, too. Thanks for the hints!
I currently use diff-so-fancy which is nice enough but as someone who looks at a lot of diffs a day this seems like a big upgrade.
$ git log | vim -
Inside vim search what you want with '/' When you find the commit you want put the cursor everywhere over the commit ID and run this normal mode command:
<Esc>:!git show <Ctrl+R><Ctrl+W><Enter>
You will be shown the diff in your default text view program (normally it's 'more' but can also be vimdiff), press <Enter> when you finish and you will be sent directly to the place where you left off.
You can also remap this behaviour to any key/alias you want.
Hope this helped!
:r !git log
find the log entry you're interested in, move the cursor over the sha1 value, type yiw to yank it into vim's " register (by default). Then open a new window by pressing ctrl-w n.In that window run
:r !git show <ctrl-r ">
where <ctrl-r "> will retrieve the sha1 value you yanked into the " register.It's fewer steps, doesn't require using the mouse, and allows you to see both the git log output and git show output in different adjacent windows. You can always press u to undo the change in the new window, switch windows to get back to the git log output, find another sha1 and repeat the process.
But for a repository I do regular development in, vim with the "fugitive" mode works very well. You can just use :Glog, and browse, hitting enter on a commit to show the full commit, or on a tree to show the tree, or on a file within a tree to show the file (at that version).
I also use :Gdiff to give a vimdiff of changes, to stage the changes I want to commit, and then :Gcommit to commit them.
Yes, I also double-click on the commit hash and copy it. But I wish there was an incrementing index starting from the top of git log, such that say the 15th commit down, I could just say `git show 15` and see that diff, instead of having to copy and paste the commit ID ( and use my mouse )
The 15th commit down can be shown with
git show HEAD~14
However, since the log itself does not show you the count this has limited utility since you’d have to either manually count or add some additional processing in order to insert counts into the output of git log.I guess if there was one git wrapper that I could use for everything, that would be better. But then I would be probably forget all the traditional git commands, and would be useless if I had to jump on another machine.
Not sure I understand this note
Does this mean that:
git commit-graph write --reachable --changed-paths
is not a persistent setting, or it is a persistent setting?There is work in progress to fix that issue, hopefully in the next version: https://lore.kernel.org/git/f1e3a8516ebd58b283166a5374843f5c...
git log -- /path/to/file
I should always execute git commit-graph write --reachable --changed-paths
first, if i've made any changes to the repo (e.g. commits), since the last time i've run it (unless I disable the configuration that automatically generates commit-graphs with fetch.writeCommitGraph and gc.writeCommitGraph) ?You don't need to rewrite the commit-graph file every time you want to run "git log". The "git log" command will parse the newer commits the old-fashioned way until you reach the commits encoded in the commit-graph file. If you do it once now, then you'll still be fast even if a few commits are added on top of your existing history.
If you update the commit-graph with that command once a week, then you'll stay fast even in a very large repository.
Thanks, this is the context I was missing.
Just wanted to avoid a "dirty read" situation.
Thank you for providing the answers here- very helpful!
At work we've renamed all `master` branches to `main`
1. https://twitter.com/xpasky/status/1271477451756056577?s=20
2. https://bitbucket.org/blog/moving-away-from-master-as-the-de...
But also my opinion is "this is stupid and doesn't matter", which makes me not really care that they did I guess.
But Microsoft is establishing a history of being political correct instead of doing the sensible thing.
Calling the default branch master is a design choice and nothing more, if you think otherwise the problem is yours.
Might not much very much, but I think showing you care is something.
If it breaks a bit of shitty tooling that relies on hardcoded values, then I think we can live through that.
For sake, I was using bazaar back then as it looked to be aiming to be user friendly but I guess everyone jumping to git killed it.
Now every new git users are crying how it's not intuitive while every developer ecosystem is being built around git.
It's the price we pay for blindly following "coolness".
But I'm not sure I'd get that much interest from other people to use "mast", it might just be something in my own projects.
> A group of literary works that are generally accepted as representing a field.
Also, the coinage "fanon" (as in derivative works by a fanbase) comes directly from the treatment of the source material as "canonical". (Frankly, "canonical" is the best argument I can make for "canon".)
master/slave goes back to Mesopotamia, 4 thousands years ago and was used to describe the relationship between men and gods
> Man was believed to have been created to serve the gods, or perhaps wait on them: the god is lord or master (belu) and man is servant or slave (ardu)
I guess being that old is not good enough nowadays
This isn't just an instance of "not old enough", it's an instance of it not even being the same word, so I guess you just can't win this...
I made the same point here
(Source: https://github.com/github/renaming)
edit: I fixed the script to use branch [0] instead of branch master (using GitPython).
Until it is accused of being sexist, or too western.
[1] Bitkeeper was the SCS that the Linux kernel had been using up to that point, and whose dropping of free licenses to open source projects like the Linux kernel was the immediate cause of the creation of both git and Mercurial.
master/slave has been with us since forever (https://news.ycombinator.com/item?id=23969906) and describes a relationship between two entities where one is the controller and the other is controlled, in many religions (including the most popular one) there is still a master God (or more than one) and believers are slave to God (with the capital G)
But in Git there is simply a "master" branch, there is no master/slave relationship, there is no hierarchy enforced, branches are just copies that diverged from the master copy, master as in master recording or "the source from which all copies will be produced"
I honestly have a hard time understanding what's problematic with it.
> master/slave has been with us since forever
"Tradition" or "we've always done it that way" is not a great excuse, especially when part of the problem is systemic papercuts. It's not surprising that systemic issues rely a lot on "tradition" to do their dirty work.
Whether or not you agree with the particular etymology/association being questioned, the very point of questioning it is whether or not this "tradition" is worth the pain of systemic papercuts. We've got a lot of other useful words, we don't have to keep using ones that cause papercuts just because of "tradition" (whether or not you personally suffer from those papercuts).
This argument comes off as very condescending in a soft bigotry of low expectations-type of way, given there's nothing else within git that even hints to master being related to master-slave terminology.
I'm sorry for slavery in US, but slavery in US is hardly the only example of slavery in history.
master/slave describes more than just a hundred years of slavery in United States
It also describes thousands of years of religious beliefs, for example.
> the very point of questioning it is whether or not this "tradition" is worth the pain of systemic papercuts
Not to sound harsh, but 5 billion people are ok with it.
It's a linguistic problem for a small minority of the population that speaks English as a native language and super charge words meaning.
Take for example the word servomotor.
A servomotor is
> French servo-moteur, from Latin servus slave, servant + French -o- + moteur motor, from Latin motor one that moves
In Italian it is "servo motore", servo is the exact translation of slave.
Why is servomotor ok, why is "I'm a slave to Jesus" or "God is my master" ok, but master branch is not?
I'm simply curious of why some people can't let things go...
Essentially there are some people who will follow rules and trends without questioning them. Among those there are some who will actively seek to punish those who do not follow the rules.
This master/slave thing is a new rule born out of guilt and virtue signalling. This comes from the fact that some people see themselves as genuinely superior to others and this makes them uncomfortable. They virtue signal in an attempt to fight against this feeling, rather than just accepting what may be true, moving on, and continuing to be a good person. It's a phenomenon that has been observed in many contexts. The most vocal homophobes are often homosexual themselves. The most vocal religious devotees often have the strongest doubts.
Every word has more than one association. The argument is not that every association for the word is negative, but that one association is extremely negative, and we have the ability to use words that have fewer negative associations, so why shouldn't we use words with fewer negative associations?
That extremely negative association certainly isn't unique to the American past either, and if you think you are immune you are likely ignoring your own past. It's maybe being promoted by Americans because Americans see it as a more recent part of their past, still are wary of scars left behind from it. (Though even that isn't uniquely American; South African Apartheid is another easy example of recent history.)
Do whatever you like. I'm not telling you what to do. I'm not telling anyone what to do. I was merely explaining the controversy. I give up. I do not understand what all this hate is about. I'm just the messenger, but I guess I can take all the shots.