9 ms·
Ask HN: What made you finally grok Git?
I've been using it for over 7 years, and while I've memorized a bunch of commands and have some idea of what the commit tree is, I'm perpetually bewildered by some of its messages or the behavior of some commands - and the only way I can fix major trainwrecks is by nuking a branch (when I'm lucky, the entire repository when not) and copy-pasting stuff until it's back to working state.
- jhellan 4y agoThis youtube made it click for me what is actually going on: Git for ages 4 and up - https://www.youtube.com/watch?v=1ffBJ4sVUb4 https://www.youtube.com/watch?v=1ffBJ4sVUb4
- cassianoleal 4y agoThis is it. I was scanning the comments to see if anyone had already posted. This talk is so simple but so effective at explaining the foundations of Git that I always tell everyone to watch it.
- politelemon 4y agoI have not grokked git — it hasn't been necessary to. Understanding some of the basics, knowing enough of the commands to run, and figuring out which StackOverflow answer applies to my current situation is good enough. If I have to spend too much time knowing its internals and delving into its philosophies, then it is not a useful tool that lets me get on with my tasks.
- JKCalhoun 4y agoAgree, sort of. I sort of get git but have never grokked it, for sure. But I don't think I should need to fully understand its internals for it to be "grokkable", an elegant thing could still be grokkable regardless. It's possible though that the tasks: diffing, branching, merging, rebasing, tagging, etc., are too elusive for "elegance", ha ha. I might add though that simple diffing, branching, merging I do more or less grok. Perhaps if git had stopped there, like my understanding did, I would feel more comfortable with it ... imposed limitations be damned. I suppose in fact I only use git in this limited capacity anyway. It's only when someone else on the team does something clever (or I screw something up)....
- rgoulter 4y agoKinda. I wouldn't be able to tell you too much about the internals of VSCode. The 'trouble' with git is, though, that what happens when you run the wrong command can vary from "easy to fix" all the way to "you just lost your work, you shouldn't have run that command". Which means you need to either be very careful anytime you run git, or you need to learn more about git to avoid the footgun aspects of it.
- lijogdfljk 4y agoIt's kinda sad though because off the top of my head i suspect it's really difficult to actually lose your work. Ie between the fact that the content store stores.. well, all content, until it's GC'd, and the obvious reflog, you can almost always get back your data. The downside to this though is the type of novice most likely to make a mistake in "losing" their data will also not know how to recover their data.
- rgoulter 4y ago> it's really difficult to actually lose your work If it's been checked into a commit, sure. But if you discard changes which haven't been checked in, then the work is lost.
- hdhdxkfchsk 4y agoget in the habit of commiting every few lines you write, and before creating a pull-request(tm) use 'git rebase -i' and cleaning up into meaningfull bit sized history. move related changes togheter, remove (squash) things that didn't make it to the end, etc. oh and never join any project that uses github and force squash-commits-on-pullrequest-merge. that is a sign that nobody there knows git or they don't care about code history. edit: and yes, some rare times, rebase -i and moving things around will cause local conflicts. do not fear them. resolve and continue. it's all code you just wrote, should be easy and is part of the understanding process.
- vanilla_nut 4y ago> oh and never join any project that uses github and force squash-commits-on-pullrequest-merge. that is a sign that nobody there knows git or they don't care about code history. First, color me offended! Second... you're not completely wrong. My git-fu is not that strong. Would you help me improve it by explaining why squashing via the GitHub UI is so bad? To me it feels like an easy way to condense 1 PR into 1 commit. For some workflows, that makes much more sense than trying to get everyone to play by the same commit semantics. But I can see how it's not as "pure" in capturing the meaning behind your commits. Maybe it would be helpful to provide an example of a situation where squashing with the GitHub UI could cause problems?
- hdhdxkfchsk 4y agowhat if I give you a book with a nice chapter index, and you just rip the index and chapter titles out and add "a book" to your collection? thats squash on merge. it's a stop gap hack to fix shitty teams who write books with chapters like "chapter 1" , "chapter two I guess, still broken", chapter 3 final" , chapter 4 final final".
- doix 4y agoWhen I realized it's just a DAG and you're just manipulating a graph and pointers. Then it just became a matter of mapping git CLI commands to how they manipulate the graph.
- spencerchubb 4y agoNow I just have to learn what a DAG is
- doix 4y agoMy bad, stands for directed (not acrylic) acyclic graph, which is just a fancy way saying a graph with no loops. Edit: yeah, it's acyclic not acrylic :).
- paulgb 4y agoacyclic, not acrylic ;)
- beaker52 4y agoBob Ross enters the chat
- TYPE_FASTER 4y ago"and over here, we'll add a few happy little change sets"
- aynyc 4y agoGod damn it. I just amazon'd some fancy acrylic paper and wonder how that would help me learn git. You owe me $6.99 + tax. /s
- radicalbyte 4y agoThis: my introduction to git involved reading an architectural overview. From that it was obvious that it was a DAG. About an hour of playing with the operations (particularly rebase!) was enough. Just goes to show the power of understanding the fundamentals of CS :-)
- iExploder 4y agogit is fine, one just needs to learn how to use it properly. one has yet to witness the abomination that is svn, sourcesafe, or "software working on my machine" delivered by a zip file in order repent and mend ones ways
- wildcow 4y agoThis made it click for me: https://codewords.recurse.com/issues/two/git-from-the-inside-out https://codewords.recurse.com/issues/two/git-from-the-inside...
- mcv 4y agoWhat's important to understand about git is that it allows time travel, and time travel enables changing history, and changing history is a really bad idea. Do not ever change the history without knowing what you're doing. In git, this means mostly rebasing and other stuff that messes with existing commits. Messing with existing commits can be fine as long as you're messing with the only existing version of that commit. Commits that exist in other branches, have been shared with other people, have been pushed to remote, etc, should be left alone. Rebasing local, unpushed single commits in your one working branch is fine. Rebasing anything else will cause problems. If rebase is causing you problems, do not rebase. Also: small commits, short branches, merge often.
- chrisshroba 4y agoI just ran into this problem last night... if you shouldn't rebase after pushing to remote, how do you update a PR days after you originally created it to be on top of the latest origin/master and be able to resolve merge conflicts locally?
- xwowsersx 4y agoNo, you only shouldn't rebase if you pushed to a shared branch. If it's your PR that only you are working on and you need to update it to the latest in the master branch, rebasing is the correct way to do this. There isn't a magical rule about not pushing to a remote branch. The point is to recognize that rebasing rewrites the history which is a problem if and only if that history has already been relied on by someone else or otherwise integrated in such a way that rewriting that history is destructive. If it's your PR, then as far as anyone else is concerned, you DID just checkout the latest from master and branch off of it. No one needs to know or care that you actually rebased.
- criley2 4y agoYou don't rebase it ontop of main after you've published it because that will mean anyone else who has checked it out will have to like checkout -f to clean it up. You just merge main in. Don't worry about extra commits that appear. PR tools like Github won't make people review them if you've done it all right, they can tell what a Merge Commit looks like (don't go deleting the auto-generated messages for merge commits unless you know what you're doing). Once you merge main into your out-of-date branch, it'll be up to date. And when you merge your branch back into main after the PR, it will work out. This is the standard way you would work on a branch with a coworker, instead of working alone. There's nothing wrong with merging main in. If you absolutely MUST have a perfect history of your commits on top of THE CURRENT state of main, start a new branch, start a new PR, IMO. Just don't change public history.
- beermonster 4y agoReading this[1] and getting the data structures/mental model correctly internalised in my head. Although I do use git from the cli (or magit) primarily, this knowledge has helped me pick-up front end tools intuitively and have helped others when I've never used their preferred tool. All of this doesn't seem possible unless you've put in the effort learning what's going on behind the scenes. That is to say, git itself it neither user friendly nor intuitive it must be learned. Knowing mercurial (hg) beforehand did slow my learning progress a bit with all the false-friends. You may find it easier to learn if you don't have to re-learn some naming. [1] https://git-scm.com/book/en/v2 https://git-scm.com/book/en/v2
- hnews_account_1 4y agoThis is my answer too. The main git book is very well written. I stopped reading just before it got into rebasing and had to pick that up from the internet due to work requirements, but the book was so solid in explaining the basics that I understood outside stuff almost immediately. I think one thing that’ll help OP, is to learn everything on the command line. The fine grain control is worth the extra effort. I’ve hated almost all git GUIs in most IDEs because they won’t let me do weird things like grafting branches which is a very advanced concept for them but once you understand git, it is a very simple operation.
- lkschubert8 4y agoPlaying through this game https://learngitbranching.js.org https://learngitbranching.js.org
- aib 4y agoBeing the go-to git guy for a whole project when everyone was new to it. Are you using it from the command line? I feel that helps a lot. Get a good log alias[1] and get hacking. I almost exclusively use the official CLI, with the exception of git-gui for committing and rolling back patches (lines / hunks). (I find it's easier than `add -p` and that CTRL+J is a good time saver.) 1: As an example, https://github.com/aib/dotfiles/blob/master/.gitconfig#L29 https://github.com/aib/dotfiles/blob/master/.gitconfig#L29
- rgoulter 4y agoThis took me from "add/commit/push, and pull" to being able to do rebases: https://learngitbranching.js.org/ https://learngitbranching.js.org/
- he_is_legend 4y agoFriends don't let friends do (non local) rebases.
- rgoulter 4y agoYou can take rebase's `--autosquash` and push's `--force-with-lease` from my cold dead hands. :o) Well, I think it's untidy to leave commits like "fix typo" or "PR feedback" in a change request, even if the whole changeset gets squashed.
- smallpipe 4y agoSame for me. This has great visualisations, I’ve not found any better explanation.
- avip 4y ago0. mental model: staging, local, remote. c'est tout 1. `git status` + gitk before and after git commands 2. guess upfront what the result of git commands will be (in terms of gitk / git status) 3. be fluent with commit, push, pull, checkout, reset, merge, and possibly rebase (I call it required but it's opinionated) - you can safely ignore the other git api in 96% of workflow
- skirmish 4y agoHaving a window of "gitk --all" always open on my repo and refreshing the view makes it really obvious what my commands are doing.
- eterm 4y agoThis altassian article: https://www.atlassian.com/git/tutorials/merging-vs-rebasing https://www.atlassian.com/git/tutorials/merging-vs-rebasing In particular the golden rule of never rebasing a public branch has served me very well and I never seem to run into the "merge hell" that others complain of.
- he_is_legend 4y agoThe trick(s) to git is not using `git add -A`, and being diligent (as in checking before you commit) about the changes that you are committing. Only add and commit what is relevant to the task that you are working on. But it's even simpler than that. Before you commit anything, check what you are about to commit. Is it what you expected? Is it relevant? Does it work? Has it been tested? Is it likely to pass a code review?
- jamil7 4y agoAgree, I tend to go through my work with `git add --patch` and committing that way. I find it also works as a quick refresh on what you actually did and helps you decide how/if to split up your work into multiple commits.
- chrismorgan 4y ago> Before you commit anything, check what you are about to commit. Better still, check it as you commit, by enabling the config option commit.verbose (e.g. `git config --global commit.verbose 1`), so that the full patch that is to be committed is shown in COMMIT_EDITMSG, not just the file names that you touched. This removes the race condition between review and commit. (While on this topic, I also recommend commit.cleanup = scissors, and reading through `git config --help`, or at least skimming it for basic familiarity with what options are available to you. A few more that I like: merge.conflictStyle = diff3, diff.algorithm = histogram, mergetool.keepBackup = false.)
- jamil7 4y agoSit down with a coffee, read the book https://git-scm.com/book/en/v2 https://git-scm.com/book/en/v2 and just spend the time learning how to use it. You'll save yourself a bunch of time and headache and won't need to be nuking repos or branches any more. There's a lot it can do, so a big part is finding out what fits into you and your team's workflow.
- mvdwoord 4y agoIntroduction to Git with Scott Chacon of GitHub - This was really helpful for me. https://www.youtube.com/watch?v=ZDR433b0HJY https://www.youtube.com/watch?v=ZDR433b0HJY
- jfzoid 4y agothis video where he explains Git's dag with tinkertoys https://www.youtube.com/watch?v=3m7BgIvC-uQ https://www.youtube.com/watch?v=3m7BgIvC-uQ
- auxym 4y agoFor me it was reading about git internals: https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Po... It made me understand how simple git really it under the hood, you just need to understand how the commands operate on this simple data structure.
- gus_massa 4y agoTortoiseGit for Windows and Git Cola for Linux. I use the command line very seldom, only for very weird things (like moving commit from a repo to another repo, but in a different internal folder).
- orzig 4y agoMake a sandbox repository and just break it repeatedly. Within the realm of basic commands, I bet you already know how to do most things (including recovering from small mistakes), but it feels too scary so you revert to non-– GIT methods. In a sandbox, you can get the reps in without any fear. You could then graduate to forking a real repo. Again experiment fearlessly, with slightly more realistic scenarios.
- AndrewDucker 4y agoGit from the bottom up. A very clear and simple guide to the internals. https://jwiegley.github.io/git-from-the-bottom-up/ https://jwiegley.github.io/git-from-the-bottom-up/
- inanutshellus 4y agoThis is a great recommendation. Concise, grounded posts that focus on the "behind the scenes" of git. After reading this I felt a much more grounded understanding of git. I don't recall if it's explicitly covered in there, but because I'd read this I understood things like what happens to my commits after I "delete" them (e.g. remove the last reference to them / hard reset to an old commit, etc).
- jlokier 4y agoSame for me. I avoided getting into Git for years (long ago when it was new, before GitHub) and found the man pages unhelpful. Git From The Bottom Up totally turned it around for me. Ever since then I've been comfortable using Git in all sorts of advanced ways, such as constructing repos from old software backups, editing decades of history to separate out publishable parts from proprietary or inappropriate parts while keeping the history, fixing broken repo issues, as well as regular daily use the way most people use it.
- fn1 4y agoUsing GitUp on the Mac as a client. It allows you to select a commit and press Options-S to reset your branch to this commit, it allows you to squash etc. And best of all it keeps a backup of your entire repository so you can undo whatever git command you just did.
- blop 4y agoIt was all magic to me until one day I finally took the time to look at git internals. You can build a valid git repo with simple unix shell commands, and that really helped me to understand the magic behind the git commands: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
- dzhiurgis 4y agoAs a beginner - each of stash, branch, staged and remote is just a swimlane, kinda like illustration here: https://nvie.com/posts/a-successful-git-branching-model/ https://nvie.com/posts/a-successful-git-branching-model/ but can't remember where did I read it initially
- pjmlp 4y agoNothing, I keep using it as if it was Subversion. With the help of IDE tooling and TortoiseGit, the command line basic stuff for workflows that might not be exposed on the graphic tools. If the repo gets corrupted, I delete it and do a fresh clone. Life is too short to bother going deeper than that.
- solardev 4y agoI just use an IDE (Jetbrains) with a git GUI built in and stop worrying about how it works
- 112233 4y agoIt's super easy to understand how git works — I'm doing it several times per month. Seriously, low-level git, while not familiar to most devs, is logical and consistent. It's the UI level that is total disaster. Don't worry, you will forget everything in a week.
- Apreche 4y agoI started using it around 2008 on the recommendation of a co-worker. I already had a lot of experience with RCS, CVS, and SVN. I understood the problems and frustrations caused by those tools, because I suffered with them for years. After reading the Git documentation I immediately understood how Git solved those problems. Then I just started using it exclusively. The end.
- furstenheim 4y agoTreat commits as immutable data. Don't try to amend, squash or rebase. Having one commit merges is overrated
- coutego 4y agoImplementing it. Once I read somewhere it is just a key - object, append only, DB then it seemed easy to implement the core of it, so I did. It's simpler that it sounds.
- coutego 4y agohttps://github.com/coutego/version-control https://github.com/coutego/version-control
- mrkeen 4y agoWhen I realised it was all about share-xor-mutate, just like all reasonable systems: Rebase and force-push on your own branches only (they are mutations), pull-request when putting stuff onto other branches. I also find the whole git tree WAY easier to read if it's fast-forward-only, and no merge commits. Atlassian's not as popular as they used to be I guess, but I found Bitbucket presents the best view of the git tree ever. When I wanted to do anything advanced, I'd look at the Bitbucket view, do local git commands in my shell, push, and then watch Bitbucket again.
- deleted 4y ago[deleted]
- readonthegoapp 4y agodon't get it yet, but learning / realizing that it can remote into other machines and execute commands (via SSH/server, so no other server software - like an HTTP server - is necessary) was definitely eye-opening.
- srhtftw 4y agoI remember Git from the inside out and Learn Git Branching were very helpful when I started using git. The Git Command Explorer was good as well. Links from my notes below: Git Command Explorer - https://gitexplorer.com/ https://gitexplorer.com/ - https://news.ycombinator.com/item?id=28888763 https://news.ycombinator.com/item?id=28888763 Learn Git Branching - https://learngitbranching.js.org https://learngitbranching.js.org - https://news.ycombinator.com/item?id=18504948 https://news.ycombinator.com/item?id=18504948 Git from the inside out - https://codewords.recurse.com/issues/two/git-from-the-inside-out https://codewords.recurse.com/issues/two/git-from-the-inside... - https://news.ycombinator.com/item?id=9272249 https://news.ycombinator.com/item?id=9272249
- ecnahc515 4y agoUsing rebase and reflog really taught me a lot about git, because it "rewrites" history and exposes you to some nuance. Like: basically nothing in git is ever gone if it was at one point committed to the repository, that includes branches you delete and never pushed, it also includes commits that are removed with git reset --hard. Once I learned about how to find references, refer to them, and manipulate them, everything else made a lot more sense.
- mshekow 4y agoTeaching Git to others (e.g. company-internal workshops). You learn so much from teaching, and also from questions others ask, helping you discover your unknown knows and unknown unknowns.
- karmakaze 4y agoMaybe the one thing that made it click for me was realizing that a branch is merely a label to a git commit hash. There can be local and remote ones and the local is aware of the remote (e.g. git pull). Checking out a branch makes it current, with filesystem matching the branch head's git fileset state. New commits get added and the branch label moved to the new head. That and a git tree view GUI or "git log --oneline --graph" and "git reflog" to undo stuff. Also, you're better off committing temp stuff on the current local branch with message "WIP" than using "git stash".
- karmakaze 4y agoHow I really learned git well though was looking in the .git/ directory. "ls .git/refs/heads" shows a bunch of files with names of local branches. And "cat .git/refs/heads/my-local-branch" shows a git commit hash. You can learn a lot about git this way, and it's first-hand knowledge that's easier to recall than reading about it somewhere.
- milliams 4y agoThe Git Parable (https://tom.preston-werner.com/2009/05/19/the-git-parable.html https://tom.preston-werner.com/2009/05/19/the-git-parable.ht...) cliched it for me.
- rapjr9 4y ago>What made you finally grok Git? When I realized what it was designed for. It was designed for one or a few people to shepherd software contributions from many people, pushing most of the work out to the masses and making the job of the shepherds easier. So it is designed kind of backwards of what you'd want for a personal project or a small team. Software integration is one of the most difficult tasks in software engineering and it requires someone who is aware of how everything operates and fits together and what the overall design is. If you use Git in a team where everyone does their own integration there is a strong likelyhood that no one actually does integration, which makes things go haywire later (when it is difficult to back out). If you don't have the resources to put someone in charge of integration (it can take a lot of time) do not use Git. Just use a good source control system and do design and integration in meetings up front (and periodically thereafter). In some sense I think Git is inefficient since it doesn't so much guide development as reject bad code. All that rejected code is wasted time that could have been used more productively with better guidance. Yet the centralized nature of control in Git makes it look like development is being guided. If the center of control is not also doing design, integration, and guidance though it creates a lot of wasted effort and failed projects. To a large extent this is true of any method of software development, but I think using Git can make it worse because it can make it easier for sub-teams to ignore integration until it is too late. Git is not magic. Getting your code to build and run is not the same as integration.
- kazinator 4y agoI don't think I've fully grokked git, but 1. There is a similarity with Lisp. A commit is an object with a pointer to the next one (or multiple parents). These objects are garbage collected. Heads point to commits: they are like root pointers. These pointers are mutating. When a new commit is made, it's a lot like a new cons cell pushed onto a list in Lisp: (push new-commit HEAD). (Stupidly, git history isn't terminated by the equivalent of NIL; yet some git operations require a parent. There are ugly workarounds.) 2. Key insight: commits store snapshots, not deltas. Diffs are calculated. I've slightly delved into the internals. 1. I developed a procedure for reordering commits on a branch with zero conflicts, using tree objects directly, without any rebase workflow. So that is to say, we peel back the brandch, and then create commits using the tree objects of the original commits, in whatever order we want. Because git is based on snapshots, there are no conflicts: it's not a rebase operation on cherry picks. 2. I went through an exercise once of manually creating a stash entry, by creating the right objects and editing some text files in .git