git diff --staged (shows the diff between the last commit and what you've got staged, great when what you're staging is finicky, lets you double check that you have precisely the files/hunks you intended)
git log <file> (git log, but for just commits where <file> was touched; saves pilfering through all of git log, especially useful when the file only gets modified infrequently)
Random tip: when using git add --patch, try the 'e' option if you need more nuance than the hunks git provides (it contains instructions for how to ex/include individual lines, so you don't have to remember how to do it).
Wow, TIL `git diff --staged` exists and is an alias to `git diff --cached`, which I have used for many years. "staged" certainly feels more intuitive, but will I ever be able to undo this muscle memory?!
> git diff --staged (shows the diff between the last commit and what you've got staged, great when what you're staging is finicky, lets you double check that you have precisely the files/hunks you intended)
If you set `git config --global commit.verbose true`, then Git will automatically include this diff in the comment section of the commit message editor.
It's like an extended git blame, showing how the specified lines evolved over time, and by who. Tracks the change as the line numbers evolve, and even as the file is moved.
Answers the questions of "who did this, when, and why?" / "How long has it been like that?", etc.
One advantage that "git blame" has over possible alternatives such as "git credit", "git author", or "git praise", is that it's one character shorter and maybe faster to type.
For the same number of characters, I have heard of "git glory" as a possible alternative.
I liked the way I learned git. I started with sourcetree, a third party git gui. Super simple to use and understand. Then I moved to git gui, this step could be skipped. Then I got tired of pulling up my UIs and learned the terminal commands. Highly suggest this for anyone new, but just my (n=1) experience.
All I know of git is clone, pull, commit, and push. That’s all I’ve ever needed. Git can be that simple. Of course it supports more complex uses, which you can learn if you need them.
The use case for more is managing the history of it in a specific way to make it easier to understand. Most applications don't need this level of management since most applications don't have lives depending on them
>Then I got tired of pulling up my UIs and learned the terminal commands
I'd never revert to terminal commands. Git is basically begging to be interfaced with through a GUI given how much sense it makes to visualize a git repo and its workflows. The moment I started using Magit git started to make sense for me.
I like GitKraken, except for the fact that it lacks the ability to show first parent only, i.e. `git log --first-parent`. That feature is available in Visual Studio and Visual Studio Code (Git Graph extension), but I don't like these as much as GitKraken, so I end up switching between command line, GitKraken and VS/Code. It's a bit of a mess. Does Fork support `--first-parent`? It's especially hand in merge-heavy workflows with very noodly graphs that you want to simplify.
Yes. Because git was created by Linus Torvalds specifically to enable and advance Linux kernel development.
The fact it has become so widly adopted is a "happy accident" (or misery). Github I think has been widely credited with making git so common place ("free git hosting") but I don't think git is the "ideal" revision control system for many projects.
Because it was made for Linus for Linus/Linux, this is why the terminology and sometimes workflow is backwards from every other "normal" version control system. A "Pull Request" (PR) is named that because for Linux development Linus/maintainers would PULL changes into Linux kernel tree. In almost every other version control system it's called a Merge Request which logically makes MUCH more sense because you are merging a change (where ever it came from) into a tree.
Git was (still?) the only open-source distributed version control system that could handle enormous code bases with good speed which means it gained a lot of inertia at big companies as well.
I vastly prefer and use Mercurial for personal projects but if you have tried to use Hg on huge code bases (I've tried on Android AOSP) it really chokes. Mercurial got the "user interface" and command-set right and has some nifty features (being able to launch a web server on the fly to get a tree view of your changes) but being written in Python, performance and scalability aren't ideal.
> Mercurial got the "user interface" and command-set right and has some nifty features (being able to launch a web server on the fly to get a tree view of your changes) but being written in Python, performance and scalability aren't ideal.
I used to think Mercurial had a better UI but I changed my mind after taking the time to understand Git. Mercurial does have nifty features but Git's way of working isn't hard or especially counterintuitive. You must learn the terminology to properly understand it, but after that it's smooth sailing. Git actually has fewer moving parts than Mercurial, as there are less extraneous features. Instead of 3 or more categories of "branch-like" graph structures like Mercurial, you get branches as refs in Git. Every named leaf in the commit graph is a branch or a tag, and those have simple properties. There are surely git plugins to add more metadata but you don't really need that.
Git too has a web interface by default: https://git-scm.com/docs/gitweb Of course there are many Github-like solutions specifically catered to hosting repos and entire project workflows with Git too.
It might also help understanding, when talking about the history of git, to keep in mind that it came to be out of the urgent need for a tool to replace (then still proprietary) BitKeeper. I wouldn't say that bk is as hard to grok as git, but it's certainly complex as well. I wonder if some of git's idiosyncrasies are a result of intentionally avoiding a look&feel equivalent to bk lest that would alienate Mr. McVoy.
Some of the complexity comes from the fact that in earlier versions it was reasonably expensive to add new subcommands. As a result more functionality got added to existing subcommands like git checkout. This made the UX more confusing.
In newer versions of git the cost of adding new subcommands is reduced and they've started adding more specific commands like git switch.
It's not needlessly complex. The workflow it was created to support is inordinately complex, and the target market for that is highly technical, so its complexity was not the issue. Kernel developers needed to communicate to other kernel developers in a decentralized manner, and needed to work on top of each other. How do you work on a project where there are 15,000 people writing code? Git was created for this purpose.
It's as complex as it needs to be to support the workflows it was designed to be. A dumber tool would be easy to create, but then it would not be able to support more complex workflows like linux kernel development. So it's not needlessly complex, though it is more complex than it needs to be for simple use cases.
For those needing a less complicated frontend, there's a large number of them to make it easier to interact with git. For people that aren't full-time software developers, I don't recommend using git directly. However for those that are, it's worth taking the time to understand the underlying concepts so git becomes something you understand because once you do, it's quite elegant for what it does. I'm not going to gatekeep being a software developer on whether or not you know git, but if figuring out for yourself how such a fundamental system works doesn't give you a release of dopamine, this might not be your kind of thing. Which is totally fine. There are tons of things that are and aren't my thing.
After learning Jujutsu, I realized this is really wrong. The underlying data structures and operations are great, and they serve their purposes really well (such as supporting 10k+ people collaborating like you mentioned). They are what makes git great. The git command line interface is a needlessly complex abstraction on top of them that tries to encourage certain behaviors, but does a really bad job at it.
"Needlessly" can be in the eye of the beholder, but given that Linus basically put it together to solve the problem he was trying to solve without consulting a UX team or building a product for the ages, I would be willing to place my probability bar pretty high on the design tilting towards "One person's best idea right now" over "Best design theoretically possible."
That having been said, the team is really good at engines so the software is quite good at doing what it's supposed to do.
Because Linus had more clout in the SE industry than anyone else and said “SVN bad” and nobody wanted to do enough research to disprove him so here we are.
Merging in Subversion is a complete disaster. The Subversion people kind of acknowledge this and they have a plan and their plan sucks, too.
It is incredible how stupid these people are.
So for example, let's go back to one of the things where I think the designers of Subversion were complete morons.
Strong opinions. That's me, right?
There's a few of them in the room today, I suspect.
You're stupid. (Crowd laughs)
Nobody is interest in branching. Branches are completely useless unless you merge them.
-p, --patch
Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to review the difference before adding modified contents to the index.
I always custom-select hunks of my current work to assemble into coherent commits, where possible. I find it really helps me to rearrange the work I've done in my head in such a way that if I needed to walk someone through it, I could do so by walking the commit line.
These have become staples of my recent workflow. Julia’s example uses HEAD^^^^^ to rebase the previous 5 commits. I have been doing this as HEAD~5, until recently I realized you can just rebase all commits up to the upstream HEAD.
I'm adopting this immediately. I always make little "oops <topic>" commits like "oops GET users/me" and then manually move and fixup them on my next interactive rebase. This is much better!
git diff --staged (shows the diff between the last commit and what you've got staged, great when what you're staging is finicky, lets you double check that you have precisely the files/hunks you intended)
git log <file> (git log, but for just commits where <file> was touched; saves pilfering through all of git log, especially useful when the file only gets modified infrequently)
Random tip: when using git add --patch, try the 'e' option if you need more nuance than the hunks git provides (it contains instructions for how to ex/include individual lines, so you don't have to remember how to do it).
I’m using git dc, but it seems ds may be my new one, haha.
In case anyone cares to browse or suggest their own: https://gitlab.com/Falimonda/gitrc
If you set `git config --global commit.verbose true`, then Git will automatically include this diff in the comment section of the commit message editor.
Answers the questions of "who did this, when, and why?" / "How long has it been like that?", etc.
Based on the above statement, I find it extremely weird to see such git command named "blame", then I realized I'm not the only one:
What does 'git blame' do? [1].
Blame someone else for your bad code [2].
Git blame should be called git credit [3].
Does Git Blame sound too negative? [4].
______________________________
0. https://skeptics.stackexchange.com/questions/19836/has-phil-...
1. https://stackoverflow.com/questions/31203001/what-does-git-b...
2. https://news.ycombinator.com/item?id=27963868
3. https://dev.to/damcosset/git-blame-should-be-called-git-cred...
4. https://www.reddit.com/r/ProgrammerHumor/comments/r5lzyo/doe...
[1] https://github.com/looshch/configs/blob/master/.gitconfig#L1...
For neutrality, 'annotate’ was another alias.
For the same number of characters, I have heard of "git glory" as a possible alternative.
I'd never revert to terminal commands. Git is basically begging to be interfaced with through a GUI given how much sense it makes to visualize a git repo and its workflows. The moment I started using Magit git started to make sense for me.
I have only praise for Sublime Merge.
Seeing this cheat sheet really brings it to life.
The fact it has become so widly adopted is a "happy accident" (or misery). Github I think has been widely credited with making git so common place ("free git hosting") but I don't think git is the "ideal" revision control system for many projects.
Because it was made for Linus for Linus/Linux, this is why the terminology and sometimes workflow is backwards from every other "normal" version control system. A "Pull Request" (PR) is named that because for Linux development Linus/maintainers would PULL changes into Linux kernel tree. In almost every other version control system it's called a Merge Request which logically makes MUCH more sense because you are merging a change (where ever it came from) into a tree.
Git was (still?) the only open-source distributed version control system that could handle enormous code bases with good speed which means it gained a lot of inertia at big companies as well.
I vastly prefer and use Mercurial for personal projects but if you have tried to use Hg on huge code bases (I've tried on Android AOSP) it really chokes. Mercurial got the "user interface" and command-set right and has some nifty features (being able to launch a web server on the fly to get a tree view of your changes) but being written in Python, performance and scalability aren't ideal.
I used to think Mercurial had a better UI but I changed my mind after taking the time to understand Git. Mercurial does have nifty features but Git's way of working isn't hard or especially counterintuitive. You must learn the terminology to properly understand it, but after that it's smooth sailing. Git actually has fewer moving parts than Mercurial, as there are less extraneous features. Instead of 3 or more categories of "branch-like" graph structures like Mercurial, you get branches as refs in Git. Every named leaf in the commit graph is a branch or a tag, and those have simple properties. There are surely git plugins to add more metadata but you don't really need that.
Git too has a web interface by default: https://git-scm.com/docs/gitweb Of course there are many Github-like solutions specifically catered to hosting repos and entire project workflows with Git too.
In newer versions of git the cost of adding new subcommands is reduced and they've started adding more specific commands like git switch.
I don’t think git is that complex for most workflows to be honest. But there is a lot of power that is available if the need arises.
It's as complex as it needs to be to support the workflows it was designed to be. A dumber tool would be easy to create, but then it would not be able to support more complex workflows like linux kernel development. So it's not needlessly complex, though it is more complex than it needs to be for simple use cases.
For those needing a less complicated frontend, there's a large number of them to make it easier to interact with git. For people that aren't full-time software developers, I don't recommend using git directly. However for those that are, it's worth taking the time to understand the underlying concepts so git becomes something you understand because once you do, it's quite elegant for what it does. I'm not going to gatekeep being a software developer on whether or not you know git, but if figuring out for yourself how such a fundamental system works doesn't give you a release of dopamine, this might not be your kind of thing. Which is totally fine. There are tons of things that are and aren't my thing.
I recommend https://learngitbranching.js.org for learning how to navigate around git.
but of course, https://xkcd.com/1597/ applies as well.
That having been said, the team is really good at engines so the software is quite good at doing what it's supposed to do.
Git is very simple. It is built on just four concepts: blobs, trees, commits, refs.
Merging in Subversion is a complete disaster. The Subversion people kind of acknowledge this and they have a plan and their plan sucks, too. It is incredible how stupid these people are.
So for example, let's go back to one of the things where I think the designers of Subversion were complete morons. Strong opinions. That's me, right? There's a few of them in the room today, I suspect. You're stupid. (Crowd laughs)
Nobody is interest in branching. Branches are completely useless unless you merge them.
https://sandeep.ramgolam.com/blog/linus-torvalds-talks-about...
Shouldn't this be: `git rebase -i HEAD~5` ?
Assuming you only want to rebase linear history.
https://stackoverflow.com/questions/2221658/whats-the-differ...