Beej's Guide to Git
317 comments
·February 5, 2025beej71
aidos
Not wrong, but since you’re mentioning vim in the context of git, might be worth adding :cq as a way to exit with a non-zero status to prevent git from finishing the commit / operation.
beej71
TIL! The funny thing about Vim is that you can have used vi/Vim for 30+ years and still learn new things. I'll add this to the Vim appendix. Cheers!
dexzod
It is the same with Git
usrme
This is a fantastic mention! I've been commenting out my commit message lines and then saving as a way to trigger this. Feeling like a caveman...
celticninja
Guilty as changed your honour
ericholscher
I usually use :q! which seems to do the same thing
alexjm
The minor difference is that :q! quits without saving but returns zero as the exit code, but :cq quits with a nonzero exit code. Git interprets the nonzero exit code as "editing failed", following the Unix convention that zero means success. If you didn't save the commit message while working on it, :q! will send the empty template back to Git, which Git is smart enough to not commit. But if you accidentally save your work partway through, :q! will still commit the message you wanted to abandon.
sangnoir
That only works if the edit buffer is blank or only has commented out lines. In other cases, such as when you're trying to cancel a `git commit --amend` that loads up the last commit message in your buffer, :q! will not cancel the commit, but :cq will.
rstuart4133
:cq is useful in a shell loop that compares two directory trees that invokes vim to let you see what's changed in every file that's different. I use it often:
((cd /tmp/t; find . -type f -print) | sort | while read f; do cmp -s {/tmp/t,/tmp/t1}/$f || vim -f -d {/tmp/t,/tmp/x1}/$f 0<&9 || break; done) 9<&0
Typing ^C to vim doesn't get you very far, so if you make a mistake causing the loop to return 1000's of files you are in for a bit of pain without :cq. The :cq triggers the break, exiting the loop.dotancohen
I just love nuggets like this. I've been using VIM for 26 years and git for about 15. I never knew about adding c. I've always felt that :q! should exit with a non-zero status code, at least if no :w had been made.
iN7h33nD
Interesting I’ve always just deleted the contents of the entire buffer and :wq to cause a failure due to lack of message
olalonde
Mnemonic to help remember: cancel quit
raju
Let me start by saying this is wonderful work. Thank you for creating such a comprehensive resource. I haven't read through it all, but one thing did catch my eye.
Section 5.1 (https://beej.us/guide/bggit/html/split/branches-and-fast-for...)
> The default branch is called main.
> The default branch used to be called master, and still is called that in some older repos.
This is not true. Git still defaults to `master`, but allows you to change the default (for future `git init` invocations via `git config --global init.defaultBranch <name>`)
See https://github.com/git/git/blob/bc204b742735ae06f65bb20291c9...
Again, thank you. If I find anything else, I will be sure to post here.
*Update*: I also feel that referring to "older repos" sends the wrong message. *GitHub* decided to make this change, causing others to follow, and finally Git itself allows for the aforementioned configuration, but it has little to do with _newer_ or _older_, but rather preference.
beej71
Hrm. I didn't realize. I unset `init.defaultbranch` and it uses `master` and prints a block of hints.
> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and 'development'. The just-created branch can be renamed via this command:
That's going to make it more "interesting" to write the fix, that's for sure.
Thanks!
junebash
Just a quick shout-out; I was one of the many many students you taught at Lambda School, and just wanted to say your instruction was one of the highlights of my time there. Thanks for doing what you do!
beej71
You're welcome! :)
unstuck3958
I read your guide to C programming as a teen, and as a firmware dev today I'm forever indebted to you.
pizzalife
Same!
patchd
Not wrong, but worth mentioning. I really found git worktrees to be crucial to my workflow and have heard very few people mention them or even know they exist. Excellent way to keep your branches from getting their streams crossed without the headache of dealing with stashes.
beej71
I was on the fence about this one. Yes, it's totally useful, but I swore after writing my comprehensive C guide I would never write a comprehensive guide again. :) So I try to decide where to cut people loose to use other resources once they have the foundation.
All that said, they are really useful. And, honestly, the chapter would be pretty short to get basic usage down... but also if you've gotten as far as grokking how branches work, it's pretty easy to pick up worktrees. The fact that lots of people don't know they exist is points for adding it just for that reason alone.
I'll mull it over. :) Cheers!
alberth
I really appreciate you offering the content as a single page.
Thanks for all your guides over the years. Truly invaluable.
VierScar
Actual Beej? Wow I remember absolutely loving reading your networking guide. It taught me so much and really showed me the depths and breadths of what can be done in code, how the net works (pun unintended), it was a great experience for me as a kid. Thanks! <3
1propionyl
I found your networking guide as a kid with only some scripting experience, and it served to get me into C programming in general, so I have a special fondness for it.
Appreciate the work! Neat to see you still writing pieces like this all these years later!
pkage
I remember reading the excellent Beej's Guide to Network Programming[0] and Beej's Guide to Unix IPC[1] as a teenager, which were incredibly approachable while still having depth—fantastic reads both and very influential on the programmer I ended up being.
[0] https://beej.us/guide/bgnet/ [1] https://beej.us/guide/bggit/
soseng
Same here! I was also a teenager in the mid-90s. And I was amazed by IRCd server code and bots. I bought a used copy of the book Slackware Linux unleashed w/CD-ROM and it had some networking code examples in C. I found Beej's Networking site because I was confused by a lot of that networking code. Became even more obsessed and went a deep rabbit hole. I spent a lot of time visiting different book stores hoping they had programming books. Bought Richard Stevens' amazing reference books and never looked back. Thanks for enabling my passion all these years later Beej!
riffraff
I remember translating Beej's network guide to Italian while learning how to use select, which I wanted to learn to make some port scanner ("grabb' I think?) go faster. Fun times.
tathagatadg
Came here to see if it was the same person, though I felt very sure with the throwback web design - back when each page had its character, and you had to save the page for offline reading so that Dad wasn't pissed at the phone bill! And when the code worked - it was validation against all the previous failures (and rejections) in life! Oh the joy of sending message from one computer to the other!
Thank you Beej.
1propionyl
+1, I have almost exactly the same story!
(I didn't read the IPC guide.)
randstring
Indeed, my first steps in network programming years ago were with the help of this excellent guide.
matt3210
I had no idea about IPC! I better go read it!
Sxubas
> The Old Command: git checkout
I didn't even know git switch existed, let alone git checkout was considered the old alternative. I feel old.
To be fair I started learning git a little less than 10 years ago but woah, I can't express how it feels that someone learning git today will be confused of why I use git checkout. Like using old fashioned language.
More on topic, this guide would've been super useful when I was learning. It is really easy to follow and covers common FAQs.
I fondly remember being intimidated by my first merge conflict, aborting it and just doing some workarounds to prevent the conflict.
Rendello
Git switch is fairly new, it first shipped in 2019.
Here's, respectively, a discussion from 2021, and a discussion from a few weeks ago. In the latter, it's brought up that `git switch` is still considered experimental by the docs:
diggan
> I didn't even know git switch existed, let alone git checkout was considered the old alternative. I feel old.
I don't think "git checkout" is considered the "old alternative", at least not yet. Last time I checked, `switch` is still experimental, I haven't even considered moving away from the workflows/commands I first learned when I picked up Git ~15 years ago. Everything I want to do still works exactly the same (`git checkout` still does the exact same stuff as before), and I'm able to collaborate with everyone else using git, why change workflow then?
juped
switch/restore are not experimental in that sense, they're experimental in the sense that they're not guaranteed stable so don't rely on them for scripts or something (I occasionally tell myself I should adopt them and get them stabilized, but then don't do it)
bicolao
It was experimental to allow the developers to tweak UI, including breaking backward compatibility if needed. But I left Git shortly after these were added. I guess nobody picked this up to finish the job (even by just removing the experimental status, since nothing has changed for years and I assume nobody complained about them).
scrapcode
I can't help but feel that Git has completely missed the forest through the trees that you can make a 30+ part guide explaining how to use it.
juped
Why are programmers so vehemently angry over the fact that a complex tool which does complex things to a complex data structure might have some complexity to it?
solidasparagus
It's the de facto tool for our industry. For the vast majority of cases, users bear the burden of that complexity without gaining much benefit. And (at least for me) it doesn't guarantee the one thing I need it to do - make sure I can never lose progress.
andrewflnr
The data structure isn't that complex. Most of the things we want to do to it aren't that complex. And yet... https://xkcd.com/1597
zanellato19
"I don't understand this complexity so this means it shouldn't exist"
keithalewis
Linus wrote it, so there's got to be a pony in there somewhere. He's the first person in the world to figure out version control software. /s
ajross
My sense, bluntly, is that if people spent half the effort learning git that they do whining about it, no one would bother making a 30+ part guide just explaining stuff you could find in a man page.
Commits are snapshots of a tree. They have a list of ancestors (usually, but not always, just one). Tags are named pointers to a commit that don't change. Branches are named pointers to a commit that do change. The index is a tiny proto-commit still in progress that you "add" to before committing.
There. That's git. Want to know more? Don't read the guide, just google "how to I switch to a specific git commit without affecting my tree?", or "how do I commit only some of my changed files?", or "how to I copy this commit from another place into my current tree?".
The base abstractions are minimalist and easy. The things you want to do with them are elaborate and complicated. Learn the former, google the latter. Don't read guides.
wruza
This doesn’t work. Look:
Commits are sets of files. They form a tree. A branch is a named location in this tree. The index aka staging area is a pre-commit that has no message. Workdir is just workdir, it doesn’t go in the repo unless you stage it. HEAD is whereafter commit will put new changes.
Do I understand git? Seems like yes. Let’s run a quiz then! Q? A.
How to make a branch? Git branch -a? Git checkout -b --new? Idk.
How to switch to a branch? Git switch <name>, but not sure what happens to a non-clean workdir. Better make a copy, probably. Also make sure the branch was fetched, or you may create a local branch with the same name.
How to revert a file in a workdir to HEAD? Oh, I know that, git restore <path>! Earlier it was something git reset -hard, but dangerous wrt workdir if you miss a filename, so you just download it from git{hub,lab} and replace it in a workdir.
How to revert a file to what was staged? No idea.
How to return to a few commits back? Hmmm… git checkout <hash>, but then HEAD gets detached, I guess. So you can’t just commit further, you have to… idfk, honestly. Probably move main branch “pointer” to there, no idea how.
If you have b:main with some file and b:br1 with it, and b:br2 with it, and git doesn’t store patches, only files, then when you change b:main/file, then change and merge+resolve b:br1/file, then merge that into b:br2 to make it up-to-date, will these changes, when merged back to already changed b:main become conflicted? Iow, where does git keep track of 3-way diff base for back-and-forth reactualization merges? How does rebase know that? Does it? I have no idea. Better make a copy and /usr/bin/diff [—ignore-pattern] the trees afterwards to make sure the changes were correct.
As demonstrated, knowing the base abstractions doesn’t make you know how to do things in git.
I don’t even disagree, just wanted to say fuck git, I guess. Read guides or not, google or reason, you’re screwed either way.
nextlevelwizard
Knowing how to make a branch is very basics of using git. If you don’t know how to do it (git checkout -b, btw) you are just outing yourself as someone who doesn’t use git or your just push to master i.e. you are only working on solo projects.
You can switch branch also with ‘git checkout’ and you just ‘git stash’ your changes.
‘git reset’ is fine to reset files, but again if you just want to ”clean” repo you can stash.
You can reset staged files again with ‘git reset’
Mo idea why you would want to checkout a random commit and the start committing from that, but you can also just ‘git reset --hard HEAD~x’ where ‘x’ is number of commits you want to go back. Hard is optional, but I assume that is what you want based on your comment.
Depends on the change. If you change different lines there will be no conflicts.
This is all basic stuff you should know if you are developing code with other people
abenga
Skill issue, it seems.
Facetiousness aside, the things you do often, you learn once and you don't really have to remember/think when doing them. Most of the esoteric operations are mostly unnecessary to burden yourself with until you actually have to do them, when you just read the documentation.
ajross
Literally every one of those questions can be trivially googled. (In previous generations and fora, this is where you'd be mocked with LMGTFY links). You just, to continue to embrace the frame, don't want to do the work.
If you insist on memorizing commands for all these tasks (of which there are many), indeed, you're going to struggle and decide you need a 30 section guide. But you don't, and want to whine about it.
> I don’t even disagree, just wanted to say fuck git, I guess.
Pretty much.
ssivark
> Commits are snapshots of a tree. They have a list of ancestors (usually, but not always, just one). Tags are named pointers to a commit that don't change. Branches are named pointers to a commit that do change. The index is a tiny proto-commit still in progress that you "add" to before committing.
This is about as useful as "A monad is just a monoid in the category of endofunctors."
It's basically a lot of words which make zero sense for a user starting to use git -- even if it happens to be the most succinct explanation once they've understood git.
> The base abstractions are minimalist and easy. The things you want to do with them are elaborate and complicated. Learn the former, google the latter.
You can't really learn the former -- you can't even see it till you've experienced it for a while. The typical user groks what it means after that experience. Correction, actually: the typical user simply gives up in abject frustration. The user who survived many months of using a tool they don't understand might finally be enlightened about the elegant conceptual model of git.
chasil
The deal killer for me, the inescapable aspect of my users, is that they insist upon checking passwords into revision control.
Because the C and PL/SQL people are on CVS, I can fix this with vi on the ,v archive.
First on TFS repositories, and now with git grep I can easily find exposed passwords for many things. But it's just SQL Server!
We will never be able to use git responsibly, so I will peruse this guide with academic interest.
Don't even get me started on secrecy management.
I am looking forward to retirement!
rblatz
The devs shouldn’t have access to prod credentials in the first place. That’s the real issue.
rswail
Sounds like you need a pre-commit hook to check.
globular-toast
There is one fundamental piece missing in your description of git that I think is the main reason people don't understand it. You have described a single DAG, but in git there are multiple DAGs. This is what it means to be a distributed version control system.
In my experience people come to git and start using it with the centralised paradigm in their heads: that there is one repo and one DAG etc. They think that their master branch is the same as "the" master branch. You just can't get good at git with this wrong understanding.
HdS84
My problem is that I always use git as a central server. Except that one time when our internal git was down and we used it peer to peer for a day. Honestly, using USB sticks for that would also have been okay.
skydhash
Or do read books and guides. But in an exploratory manner. So when you do have a need for a specific operation (which happens rarely) you have a mental map that can give you directions.
rtpg
I think the trickiness with the simple abstraction is that you end up looking at a commit graph and thinking "I would like to make a couple new nodes in this in a very specific shape, but one that many people have likely done in the past. Is there a trick?"
Like so much of the porcelain is those kinds of tricks, and make otherwise tedious work much simpler.
Imagine if you didn't have interactive rebases! You could trudge through the work that is done in interactive rebases by hand, but there's stuff to help you with that specific workflow, because it is both complicated yet common.
I think jujutsu is a great layer over git precisely because you end up with much simpler answers to "how do I change up the commit graph", though.... the extra complication of splitting up changes from commits ends up making other stuff simpler IMO. But I still really appreciate git.
billdueber
Sigh. Another git thread, another pile of posts telling me that if I would _just do the work_ to understand the underlying data structure I could finally allow myself to be swept up in the _overwhelming beauty_ of the something something something.
The evidence that the git UI is awful is _overwhelming_. Yes, yes, I’m sure the people that defend it are very very very very smart, and don’t own a TV, and only listen to albums of Halloween sounds from the 1950s and are happy to type the word “shrug“ and go on to tell us how they’ve always found git transparent and easy. The fact is that brilliant people struggle with git every single day, and would almost certainly be better served by something that makes more sense.
Izkata
GP isn't describing the underlying data structures, they're describing the basic interface of commits, branches, and tags. The 101 stuff you have to learn regardless, for any version control, not just git. Dismissing it like this just sounds like someone who refuses to hold scissors by the handles.
jeroenhd
There are tools for the UI part. Most people I know only use command line git for doing stuff where GUIs give up (i.e. fixing repos in weird states). Usually, checking out a clean clone and switching to that will do the same without the GUI, just takes a bit longer if you know the command line fixes.
The issues most people seem to have with git are common version control issues. Version control is actually hard, even if it's just "what has changed", once you start going beyond two users editing a file at once. When three people edit a file at the same time, there's going to be complexity when those changes need to be applied back, and that's where you start getting into branching/merging/rebasing.
Just like some people simply cannot get functional programming/object oriented programming/imperative programming to click in their head, others will never truly grasp version control. It's a paradigm of its own. People who know lots of data structures like to trivialise version control into data structures ("it's just a list of ...") but the data structures are the chosen solution, not the problem.
Another complexity issue is that git is actually pretty smart, and will fix most problems automatically in the background. Often, when you need to manually operate on a git repo, you're in a situation where git doesn't know what to do either, and leaves it up to you as the expert to fix whatever is going on. And frankly, most people who use git are nowhere close to experts. The better Git tooling gets at fixing these situations for you, the worse your situation will be once you need to manually correct anything, and the worse your perception might get.
I have no good advice for you on how to work Git better. All I can say is that I'm very productive with Jetbrains' IDE integration, others seem to prefer Visual Studio Code's git integration, and then there's the Tortoise people. Find whatever tool works best for you and hope you'll have a random epiphany one day.
_proofs
perhaps it is time to take some personal accountability instead of lamenting the complexity in order to avoid the (overwhelming) challenge and learning.
yes, to understand an application, you must also understand the underlying data structures, architectures, models, use cases -- i am not sure what there's to roll eyes at. but there's no requirement that says that understanding has to be deep in order to work on it, or use it.
i think if you treat it like cleaning a large room, by picking out one corner at time and focusing on cleaning that before moving on, you'll find that the room is cleaned in no time, and git isn't anywhere nearly as complicated as it may feel.
there is absolutely no reason to digest a guide this dense for use-cases in every day production settings, bc those usages only make up about 10% of what this guide covers.
yes, learning things can be overwhelming, challenging, full of darkness and terrors, but that's what learning is, until you've learned.
but here is the catch imo: once you've learned, you don't stop learning and the challenges don't go away. you just become better at navigating the darkness, bc you get better at learning and managing feelings of overwhelm and confusion which are by products of complexity -- real or perceived or both.
jump in. it ain't that scary, even if it feels scary. i promise. i've been there, and you can overcome it.
ajross
Pretty much, yeah. Just do the work. It's not nearly as hard as whatever it is you're committing into it, I promise. Continuing to mock it via florid metaphor doesn't help anyone at this point.
gitgood
I don't struggle with git, and I can assure you, I am not brilliant. I do, however, refuse to give up when something seems hard, and I refuse to ask the computer to be easier for me. (Understandably, I started programming computers to make them do what I wanted them to do, not to sit and whine when they didn't.)
zelphirkalt
Which brilliant people, who have put in an appropriate amount of time into learning any (D)VCS, are struggling with having a day to day working knowledge/familiarity with git? Can you point to some? Brilliant people is of course a definition question. But one of the defining qualities I would ascribe to a brilliant person, is the ability to quickly grasp concepts and ideas and reason about them. That seems to me to be the core quality one needs to use git, since it requires one to have a mental model, whether actually correct (which I think few people have) or just close enough to be useful.
ggregoire
I can make a 5 line HN comment explaining how to use git:
1. git clone
2. git checkout
3. git pull
4. git add + commit + push
5. git reset / rebase
macjohnmcc
And still shoot yourself in the foot.
verandaguy
Eh, yes and no.
Git porcelain stuff's plenty good for probably 95% of users. `rebase -i` comes with a guide on which commands do what, and you could write a couple of paragraphs about how to format `git log`'s output with your own preferences and tradeoffs -- and porcelain usually includes stuff as eclectic as `git gc`, `git fsck`, and `git rev-parse` by most accounts.
Git plumbing's definitely a bit more obscure, and does a bunch of stuff on its own that you can't always easily do with porcelain commands because they're optimized for the common use cases.
TL;DR: while Git's big (huge even), a lot of what it provides is way off the beaten path for most devs.
rtldg
With 'gitk' I'm not sure I'll ever have to learn how to use 'git log'. A Good Enough preinstalled GUI is too convenient
ujkiolp
not my experience - almost always some edge case leads me to a git rabbit hole
tldr: even if you never plan to use anything advanced, you’ll end up in some weird situation where you need to do something even if you’re in the “95% of the users”
no shade, yes ofc you “could this, could that” to make things work and we have been stuck with this for so long that an alternative doesn’t even seem plausible
sampullman
I can't remember the last time I ended up in a weird situation, I stick to basic options with init,clone,fetch,checkout,branch,commit,rebase,remote,log,stash,cherry-pick,blame,config.
It did take maybe a year or so to develop the mental model of the how commands map to the underlying structure of commits, and another few years to avoid footguns (like always "push --force-with-lease").
So I think it is probably too complicated and would be happy to switch to a better alternative if one comes up, but what seems really implausible to me is going back to the bad old days of SVN.
20k
Honestly, 99% of the pain of git is simply because people use it through the CLI. If you use tortoisegit or a visual tool, you don't need to worry about any of this because its self explanatory, and it becomes trivial to use
Learning git like this is honestly just hampering yourself
wruza
I’ve seen tortoise users break their repo, struggle to understand the issue and then push it through, making it everyone’s problem. Git language is screwed, you cannot unscrew it with a right-click gui because you basically click some latin-looking hieroglyphs that you don’t know either way.
globular-toast
I highly doubt tortoise or any tool can "break" a repo. This might be a sign that you don't understand git either. Now I'm sure it can lead to people who don't know what they're doing doing the wrong thing, but if they're allowed to push somewhere and make it someone else's problem, that's not their fault. They've been forced to use git, so there should be someone else who actually understands git.
crabbone
Not at all. Not in the least.
The worst part about Git is the bad defaults. Seconded only by mismanaged storage. Or maybe being designed for the use-case most of its users will never have. Or maybe horrible authentication mechanism. Or maybe the lack of bug-tracker or any sensible feedback from its developers.
None of this can be helped by the GUI. In fact, beside Magit, any sort of front-end to Git I've seen is hands down awful and teaches to do the wrong thing, and is usually very difficult to use efficiently, and mystifies how things actually work. But, even with Magit, I'd still advise to get familiar with CLI and configuration files prior to using it: it would make it easier to understand what operations is it trying to improve.
maccard
I use the IntelliJ family of IDEs and the number of times I’ve had to reach for the cli for day to day use is incredibly close to 0. It handles GitHub auth, PR’s, branching and merging, rebase, and local branch switching pretty much effortlessly
zelphirkalt
Learning it like this makes one learn the concepts though and build something closer to an actual understanding. I have seen people struggle with understanding what git does or with making fine grained commits or mostly atomic commits a lot, especially GUI users, because many of them do not have the underlying concepts understood well enough.
tonyedgecombe
I think you could use a CLI and still not really understand the core concepts.
20k
Knowing how to do it through the CLI adds nothing to your understanding of the concepts though. Its just whether or not you have to remember an opaque CLI command, or you get a UI to click
jeroenhd
I disagree. Version control is kind of a pain, you need to understand some of the underlying concepts or you'll break your git repo in spectacular ways.
The command line isn't that hard to use if you've ever used the command line before. Beginners trying to learn git and command line at the same time (which is very common) will get utterly confused, though, and for a lot of beginners that's the case. The only difficult part with git over the command line is fixing merge conflicts, I'd recommend anyone to use any IDE rather than doing that manually.
No IDE will be of any help for getting back to normal when you get into a detached HEAD state, which IDEs will gladly let you do if you click the right button.
ycombinator_acc
Git GUIs like Turtois, Cracken, Lens, VSCode's Source Control are opinionated and for some reason all do weird stuff under the hood. If you look at the commands being run, a simple action or click in the menu results in a combination of 2, 3, 4 git commands that often resemble nothing like how I (and I imagine most people) would do it in CLI.
This is just asking for trouble.
null
nextlevelwizard
I feel like when people talk about replacing programmers with AI they are talking about people who can’t even grok git
agumonkey
depends, you could live on a UI for a start, but script git cli gives you very high speed.. it's kind of a timeline database for your code
dijit
Well, what's terrifying is that the guide is so long.
I am aware that beej's guides are typically quite comprehensive, but the vast nuances of git truly eluded me until this.
I guess Jujitsu would wind up being a much slimmer guide, or at least one that would be discoverable largely by humans?
beej71
With most of my guides I try to make it so you can quit reading when you feel you've read enough. No need to read the whole thing.
And on that note, I feel like the guide covers maybe 10% of Git :), but hopefully 90% of common usage.
babuloseo
can I repost this on leddit
djeastm
>And on that note, I feel like the guide covers maybe 10% of Git
guh
I'm just going to be emailing myself versions of files with MyFile.Final.RealFinal2.txt from now on
Izkata
Skimming over it, it looks like it's just been expanded out way more than what most guides would do. Like other guides would use a paragraph or two for what this one has spread over several sections with extra examples.
gitgood
[flagged]
nomilk
The guide is comprehensive, on the other extreme, this one-pager contains 90% of git commands you'll ever need: https://wizardzines.com/git-cheat-sheet.pdf
vvpan
It tells me that git is the wrong tool for the majority of people but it just happened to stick.
stephen_g
I think it's probably the opposite, Git has amassed a lot of complexity because it's been adapted to being a tool that is able to can satisfy the majority of requirements.
I've never found that I need to touch most of it in the 15 or so years I've been using it, but it's there if your project needs it.
riffraff
Git was always confusing to use. There's a reason it has gained a "switch" command, and that's because the "checkout" command was confusing, while being there from the beginning.
Probably you've been using it for ten years or more at this point and have internalized it, but when it came out git felt way more confusing than other VCSs.
Compare git diff with hg diff for example.
crabbone
Nope. It was initially built for the use-case most people will never have: multiple remotes that work on a project with multiple similar products each with its own set of differences from the others, with emphasis and dependency on Unix tools and text-only emails.
Most Git users will never have more than one remote per project, and so will only have a single product built from their source code. Probably wouldn't even know how to configure their mua to send text-only emails, in case that option is even available to them, and would struggle with basic Unix utilities like Vim and diff.
I don't know why Git won the VCS contest. But, I'm afraid, as with many such wins, there wasn't a clear rational reason why it should have won. It didn't make some of the obvious bad decisions which would disqualify it, but so did a few others. My take on this is that communication tools naturally gravitate towards monopoly, so, if one starts to win even slightly, the win will become a landslide win.
Barrin92
No. Git is a complex program but version control is an inherently complex problem that requires powerful tools. There's certain set of problems where, as a programmer, you're going to have to sit down and actually read the book.
The universe doesn't owe you an easy 10 minute video solution to everything, it's an annoying educational expectation that people seem to have developed. Some things are just that difficult and you have to learn them regardless.
forrestthewoods
No. Source control is not that complicated. Git is just bad. As an existence proof: Mercurial is much better and simpler.
I can teach someone who has never even heard of source control how to use Perforce in about 10 minutes. They will never shoot themselves in the foot and they will never lose work. There are certainly more advanced techniques that require additional training. But the basics are very easy.
Git makes even basic things difficult. And allows even experts to shoot their face off with a rocket launcher.
Git sucks. The best tool doesn't always win. If MercurialHub had been founded instead of GitHub we'd all be used a different tool. Alas.
CamperBob2
No. Git is a complex program but version control is an inherently complex problem that requires powerful tools.
That's the thing. For most developers, it's not, and it doesn't. I have never needed a VCS that couldn't be wrapped in a few batch files like add.bat, get.bat, put.bat, diff.bat, merge.bat, and list.bat. You can do the same thing with git, of course, but just understanding enough about it to write the batch files practically takes a semester of study.
Unless your job is to maintain the Linux kernel, git is probably not the right tool for your job. But it 'won the source control war', so... git, it is.
stcroixx
I was a developer for a long time before git and used many different VC systems. Didn't need to read the book on any of them and had no problems. For most cases, VC is simple. Git is just designed for this complicated case that applies to a tiny sliver of developers. I've never once pushed to more than one remote in like 10-15 years of using it.
mbonnet
git can suck, but it's the best tool we've got for the job.
elevatedastalt
I regularly conduct 2 hr long "Intro to the Git Data Model" courses at my workplace (1-2 times a year). I literally take them into the .git directory and unzip the files to show how everything is just plain text representation of basic data structures. It's honestly cool to see it click in their heads.
We have a basic Git cookbook we share with any new joinees so that they start committing code, but most of them just follow it religiously and don't understand what's going on (unsurprisingly).
However, literally everyone who attends the course comes out with a reasonable working understanding of Git so that they know what's actually happening.
That does NOT mean that they know all the commands well, but those can be trivially Googled. As long as your mental model is right, the commands are not a big deal. And yet, the vast majority of the discussion on HN on every single Git post is about the command line.
Funnily enough the class sounds a lot like the alt text of https://xkcd.com/1597/ (Just think of branches as...), the difference is that that is unironically the right way to teach Git to a technical audience, and they will come out with a fundamental understanding of it that they will never forget.
I honestly think it's such a high ROI time investment that it's silly to not do it.
lucasoshiro
I did it once, I was indeed really nice, and the discussion that we did after was very cool. I put in the last slide of the presentation some questions for my colleagues answer based on the Git data model, e.g.: "Can we move a commit to another branch?" or "What guarantees that we don't have cycles in the commit graph". I was really satisfying that people came out thinking Git, not only using it!
elevatedastalt
Exactly, and it's such a high success rate!
This is precisely why it enrages me when all HN discussion about Git devolves to the same stuff about how it's complex and this and that.
A technical person who has general sense about basic data structures (Leetcode nonsense not needed) can be taught Git in under 2 hours and they will retain this knowledge forever.
If you can't invest that little time to learning a tool you will use everyday and instead will spend hours Googling and blindly copy-pasting Git commands, that's on you, not on Git.
lucasoshiro
Perfect!
Git is only a directed graph with the adjacencies stored as hashes. Everything else is just tooling around that data structure. No problem using Google to find the commands (the Git CLI is very inconsistent...) but if you know what you want to do with that data structure you can find precisely the commands for that.
o11c
That last question is a cryptography question in disguise; the answer is "the fact that SHA-1 collisions are still impractical for most people".
lucasoshiro
Correct!
Even though SHA-1 collision were achieved, they are impractical and we can make the assumption that "if two objects has the same hash, they are the same".
To have a cycle, both commits involved would need to have the hash of the other, which is impossible: the hash of a commit is based on its content, its content contains the hash of its parent.
We could only have a cycle here if we create two commits created after two arbitrary hashes.
sundarurfriend
> As long as your mental model is right, the commands are not a big deal.
A priori, I would have assumed this was one of those "just understand how every layer and every part of Linux works, and using Linux is easy" type arguments people used to make in the 90s - i.e. theoretically true, practically infeasible for most people.
Thankfully, I was lucky enough to come across a video explaining (some of) the git internal model early on, and it really doesn't take that much or that deep a knowledge of the internals for it to make a big difference. I'd say I know maybe 5% of how git works, and that already gave me a much better understanding of what the commands do and how to use them.
AnonHP
> I regularly conduct 2 hr long "Intro to the Git Data Model" courses at my workplace (1-2 times a year)
Does the course material (and perhaps any recordings) have any proprietary information or constraints to prevent you from sharing it publicly? Is this based on something that’s publicly available yet concise enough to fit within two hours? If yes, please share (perhaps in this thread and as a post submission on HN).
I’m asking because I believe that there can never be enough variety of training materials that handle a topic with different assumptions, analogies, focus, etc.
nomilk
Is there a copy/video of your talk, or a similar one you recommend?
raju
Posted this comment https://news.ycombinator.com/item?id=42961468
Happy to get any feedback.
valenterry
Share your video!
raju
Not the OP, but I've been teaching along similar lines. I've done it a couple of times at conferences—here's one of the versions: https://www.youtube.com/watch?v=8Q-frNO-yps
I've also blogged about it
- https://looselytyped.com/blog/2014/08/31/gits-guts-part-i/
- https://looselytyped.com/blog/2014/10/31/gits-guts-part-ii/
BeetleB
I'm decent with git (usual flow, merging, rebasing, etc). I'm seriously considering switching over to jujutsu instead of becoming "better" at Git. jj is compatible with git and you can use it while your teammates can also just use git.
globular-toast
I feel like there is a trick that is missed by many guides (including this one) and most git GUIs I've looked at (with notable exception being magit).
That is, to set your upstream branch to the branch you want to merge into, aka the integration branch. So instead of setting upstream of "feature/foo" to "origin/feature/foo", you would set it to "master" or "origin/master".
This simplifies a lot of things. When you run `git status` it will now tell you how far you have diverged from the integration branch, which is useful. When you run `git rebase` (without any arguments), it will just rebase you on to upstream.
Setting `origin/feature/foo` to upstream is less useful. Developers tend to "own" their branches on the remote too, so it's completely irrelevant to know if you've diverged from it and you'll never want to rebase there.
If you set `push.default` to "current", then `git push` will do what you expect too, namely push `feature/foo` to `origin/feature/foo`.
Why isn't this a more common setup?
ptx
In the collaboration section, the guide doesn't mention feature branches at all. Isn't that a very common way of working? Contrasting it to the "Everyone Uses Their Own Branch" approach described in the guide might be informative.
Also, reusing branches for GitHub pull requests (vs. creating new branches for each PR) might warrant some discussion in section 17?
leonseled
Haven’t checked out the article, I’m sure its great. But another reco is boot.dev’s git course taught by Primeagen. It’s interactive and He goes real deep down to manipulating files in the .git directory. Came out of that course with a whole new mental model of how git works.
dcchambers
Love seeing this. Beej is one of the greatest in our industry. His educational content is top notch and always free...an increasingly rare thing in the age where everyone tries to monetize their knowledge via paid courses and newsletters.
Keep on fighting the good fight, Beej.
zeroq
I think the biggest problem with CVS is the lack of consensus on what and how to push to the repo.
On one hand you have the ideal world scenario when each and every change is granular and you can annotate and blame every single line of code with description. On the other hand you have a real world where teams are encouraged to squash changes so that every commit corresponds to a business requirement and you have to engage a whole cabal to smuggle a refactor.
A long time ago I've implemented a routine to use both SVN and GIT, so that I could use GIT on file save, and SVN on feature release. I think it was inspired by Eclipse workflow. Definitely not something I would recommend these days.
Hey all--if you find things wrong, post 'em. I'll clean 'em up. :)
Love, Beej