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.
When I realized it's just a DAG and you're just manipulating a graph and pointers.<p>Then it just became a matter of mapping git CLI commands to how they manipulate the graph.
I 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.
What'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.<p>Messing with existing commits can be fine <i>as long as you're messing with the only existing version of that commit</i>. 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.<p>Also: small commits, short branches, merge often.
This youtube made it click for me what is actually going on:<p>Git for ages 4 and up - <a href="https://www.youtube.com/watch?v=1ffBJ4sVUb4" rel="nofollow">https://www.youtube.com/watch?v=1ffBJ4sVUb4</a>
Nothing, I keep using it as if it was Subversion.<p>With the help of IDE tooling and TortoiseGit, the command line basic stuff for workflows that might not be exposed on the graphic tools.<p>If the repo gets corrupted, I delete it and do a fresh clone.<p>Life is too short to bother going deeper than that.
get 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.<p>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.<p>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.
Git from the bottom up. A very clear and simple guide to the internals.<p><a href="https://jwiegley.github.io/git-from-the-bottom-up/" rel="nofollow">https://jwiegley.github.io/git-from-the-bottom-up/</a>
I remember <i>Git from the inside out</i> and <i>Learn Git Branching</i> were very helpful when I started using git. The <i>Git Command Explorer</i> was good as well. Links from my notes below:<p>Git Command Explorer<p>- <a href="https://gitexplorer.com/" rel="nofollow">https://gitexplorer.com/</a>
- <a href="https://news.ycombinator.com/item?id=28888763" rel="nofollow">https://news.ycombinator.com/item?id=28888763</a><p>Learn Git Branching<p>- <a href="https://learngitbranching.js.org" rel="nofollow">https://learngitbranching.js.org</a>
- <a href="https://news.ycombinator.com/item?id=18504948" rel="nofollow">https://news.ycombinator.com/item?id=18504948</a><p>Git from the inside out<p>- <a href="https://codewords.recurse.com/issues/two/git-from-the-inside-out" rel="nofollow">https://codewords.recurse.com/issues/two/git-from-the-inside...</a>
- <a href="https://news.ycombinator.com/item?id=9272249" rel="nofollow">https://news.ycombinator.com/item?id=9272249</a>
For me it was reading about git internals:<p><a href="https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain" rel="nofollow">https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Po...</a><p>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.
I don't think I've fully grokked git, but<p>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.)<p>2. Key insight: commits store snapshots, not deltas. Diffs are calculated.<p>I've <i>slightly</i> delved into the internals.<p>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.<p>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
Being the go-to git guy for a whole project when everyone was new to it.<p>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.)<p>1: As an example, <a href="https://github.com/aib/dotfiles/blob/master/.gitconfig#L29" rel="nofollow">https://github.com/aib/dotfiles/blob/master/.gitconfig#L29</a>
>What made you finally grok Git?<p>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).<p>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.
Sit down with a coffee, read the book <a href="https://git-scm.com/book/en/v2" rel="nofollow">https://git-scm.com/book/en/v2</a> 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.
It was all magic to me until one day I finally took the time to look at git internals.<p>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:<p><a href="https://git-scm.com/book/en/v2/Git-Internals-Git-Objects" rel="nofollow">https://git-scm.com/book/en/v2/Git-Internals-Git-Objects</a>
Reading this[1] and getting the data structures/mental model correctly internalised in my head.<p>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.<p>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.<p>[1] <a href="https://git-scm.com/book/en/v2" rel="nofollow">https://git-scm.com/book/en/v2</a>
It's super easy to understand how git works — I'm doing it several times per month.<p>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.
Using 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.<p>And best of all it keeps a backup of your entire repository so you can undo whatever git command you just did.
Maybe 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.<p>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".
This made it click for me: <a href="https://codewords.recurse.com/issues/two/git-from-the-inside-out" rel="nofollow">https://codewords.recurse.com/issues/two/git-from-the-inside...</a>
This took me from "add/commit/push, and pull" to being able to do rebases:
<a href="https://learngitbranching.js.org/" rel="nofollow">https://learngitbranching.js.org/</a>
When I realised it was all about share-xor-mutate, just like all reasonable systems:<p>Rebase and force-push on your own branches only (they are mutations), pull-request when putting stuff onto other branches.<p>I also find the whole git tree WAY easier to read if it's fast-forward-only, and no merge commits.<p>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.
Using 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.
The 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?
Make 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.<p>You could then graduate to forking a real repo. Again experiment fearlessly, with slightly more realistic scenarios.
I 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.
This altassian article: <a href="https://www.atlassian.com/git/tutorials/merging-vs-rebasing" rel="nofollow">https://www.atlassian.com/git/tutorials/merging-vs-rebasing</a><p>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.
As a beginner - each of stash, branch, staged and remote is just a swimlane, kinda like illustration here: <a href="https://nvie.com/posts/a-successful-git-branching-model/" rel="nofollow">https://nvie.com/posts/a-successful-git-branching-model/</a> but can't remember where did I read it initially
0. mental model: staging, local, remote. c'est tout<p>1. `git status` + gitk before and after git commands<p>2. guess upfront what the result of git commands will be (in terms of gitk / git status)<p>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
The Git Parable (<a href="https://tom.preston-werner.com/2009/05/19/the-git-parable.html" rel="nofollow">https://tom.preston-werner.com/2009/05/19/the-git-parable.ht...</a>) cliched it for me.
Introduction to Git with Scott Chacon of GitHub - This was really helpful for me.<p><a href="https://www.youtube.com/watch?v=ZDR433b0HJY" rel="nofollow">https://www.youtube.com/watch?v=ZDR433b0HJY</a>
this video where he explains Git's dag with tinkertoys
<a href="https://www.youtube.com/watch?v=3m7BgIvC-uQ" rel="nofollow">https://www.youtube.com/watch?v=3m7BgIvC-uQ</a>
TortoiseGit 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).
Teaching 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.
don'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.
git is fine, one just needs to learn how to use it properly.<p>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
Implementing it.<p>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.