21 ms·
Git Branches: Intuition and Reality
- xanderlewis 3y ago> in general, even if people’s intuition about a topic is technically incorrect in some ways, people usually have the intuition they do for very legitimate reasons! This is worth an essay of its own.
- webstrand 3y agoI'm still missing what part of the intuition is incorrect? It seems like the only "incorrectness" is that there's no explicit hierarchy of branches. Except that's wrong the HEAD ref points to the default branch. Any other branches are of equal significance, though.
- mgerdts 3y agoIntuition would be that the branch starts at the point that it diverges from main, labeled “base” in the first diagram. In reality, the first commit in “main” and “branch” are the same commit. Intuition likely comes from how a tree (fir or oak, not binary) is structured. Generally a branch starts at the trunk or some other branch, not at the ground where the trunk gives way to roots.
- jancsika 3y agoI don't agree with the author here. Intuition is travelling down main path that has branches which diverge and re-merge into the main path. That's why people seem to intuitively get "merging" back into main, whereas that doesn't generally make sense for physical trees.
- Sharlin 3y agoNo, the HEAD ref points to whatever branch is "active", that's how the active branch is defined. Indeed `git checkout branchname` does nothing except make HEAD point to the commit that `refs/heads/branchname` points to. The intuition jvns meant is the idea that a branch only constitutes the commits since the point of divergence, but every branch actually contains the full history up to the root of its tree, and `git log` of course shows that. (If you want to only show the commits specific to a branch, you can do `git log parent..branch`. Note also that two branches need not have any common history, it's perfectly possible for a git graph to be disconnected.)
- xorcist 3y ago> `git checkout branchname` does nothing except make HEAD point to the commit You probably know this, but since we are being pedantic we might as well get it right: That describes "git reset". "git checkout" does that and record that we are tracking branchname. So any commits will move both HEAD and the branchname reference.
- Izkata 3y agoWell along those same lines, making a commit doesn't move HEAD, it's still pointing at the same branchname as before. cat .git/HEAD
- zestyping 3y agoThe intuition is that a branch consists of a line of commits off of a trunk. Like, you know, what the word "branch" means in real life. But in git, a branch doesn't "contain" anything. It is just a pointer to a single commit. This is completely counterintuitive and makes no sense to most people at first, for a very good reason: the analogy is misleading. These things shouldn't be called branches. They are pointers: they can be repointed anywhere, dereferenced, and copied by reference. HEAD is also a stupid term, because it doesn't refer to the head of anything. HEAD is the current pointer, and it can point to any commit, not just the head of a branch. It should be called something like "here". The "detached HEAD" warning is scary and useless. Just look at these two commands, which do very similar things but look totally different: git checkout -b staging git branch -f staging 3d1b582 They are just pointer assignments. Wouldn't it make a lot more sense if they were written like this? git point staging here git repoint staging 3d1b582
- mwexler 3y agoI guess. To me, the opposite is a more worthy essay: why, with all the power to customize our tech, do we create things that consistently work differently than people's intuition? The fact that it "mostly jibes" feels like a footgun, not a feature. I get that for some, "git just works! It made sense from day one" but in my limited experience, 0% of people I've worked with have said that. Sure, we can all learn the tech. And expert techniques in any field often don't jibe with naive expectations. But for me and the folks I work with, the tech industry feels like it's gliding more towards inscrutible tools vs ease of use. We've hit a stage where many rely on code completion bots and answer-supplying bots instead of being able to directly embrace our tech. I wish the tech was more approachable on its own, but perhaps this is the natural evolution of things.
- xanderlewis 3y agoThat doesn’t seem like the opposite to me. It seems like the same thing. Rather than rejecting people’s intuition as ‘understandable but wrong’ why don’t we use it as the basis for a better solution?
- atq2119 3y agoYou do have a point, but it's not a slam dunk. Intuition isn't some fixed thing but arises from personal experience. A lot of that is common to a culture, but there are different cultures and in any case, some truly personal aspects remain. There needs to be a balance between creating new, more powerful intuitions, and meeting people at the intuitions they already have. Case in point, Git's branching model is pretty intuitive when you understand how Linux kernel development works. Perhaps 0% of the people you've worked with have looked into that. That's fine. Different cultures... Another example that may be worth studying is mathematics and the hard sciences. Learning those is a lot about learning powerful intuitions.
- BlueTemplar 3y agoYeah, few things are actually "intuitive". "Shared familiarity" is probably a better term.
- 3y ago
- informalo 3y agoYup. If it works, it ain't stupid.
- adaboese 3y agoI cannot be the only one that gets away with only knowing: git pull git merge x git checkout [-b] foo git commit git push
- baggy_trough 3y agoYes, this is very good. Also, rebasing is evil.
- gear54rus 3y agoBecause your IDE shows line-based blame and allows to check out old file versions via right-click? :) Mee too
- deleted 3y ago[deleted]
- mixedmath 3y agoPossibly `git branch NEWBRANCHNAME` instead of `git checkout -b NEWBRANCHNAME`. When I need to show git to someone in order for them to contribute to something, I give them only these incantations --- and instructions to ask me if weird git things happen.
- rkangel 3y agoYou then need to do both `git branch xxx` and `git checkout xxx` though. If you teach "checkout to move around and add -b when moving to a new branch the first time" that works pretty well
- still_grokking 3y agoIt's `git switch [-c]` nowadays.
- someone7x 3y agoI've given up trying to configure git push the branch I'm on so I type this little dance each time : git switch -c foo git push > did you mean git push --args-with-branch-name? sigh, copy, paste, enter
- zdw 3y agoA lot of things in git are just pointers to commits, and then the git implementation handles them under the covers in some way that usually makes sense but not always. One example that also bites people: moving files isn't stored in git - if you move files (even with `git mv`) and create a new commit, the moves aren't stored, but this is reconstructed later by the client based on similarity, which comes from the diff algorithm. And git has multiple diff algorithms to pick from: https://git-scm.com/docs/git-config#Documentation/git-config.txt-diffalgorithm https://git-scm.com/docs/git-config#Documentation/git-config... And optionally to not detect renames in diff output with `diff.renames`: https://git-scm.com/docs/git-config#Documentation/git-config.txt-diffrenames https://git-scm.com/docs/git-config#Documentation/git-config...
- keybored 3y agoYup. “Storing moves” is the kind of thing that might sound intuitively obvious but then gets gnarly and non-obvious when you think about it for five minutes. And so something that might be “obvious” to do then turns out to be so non-obvious—how to catch all file moves (intent) outside of simple identitical content cases, and how do you represent them internally?—that you realize that just using snapshots is really the best thing to do.
- hyperthesis 3y agoBitKeeper already did it.
- lubutu 3y agoI think this is the one thing I feel BitKeeper does better than Git. Git can get confused about where a file came from, for moves but especially for copies, and so the version history ends, even if you ask it to try and follow along. BitKeeper, on the other hand, keeps the moves and copies as part of the history, so you can always trace it through to the origin of the file, no matter how circuitous.
- account42 3y ago
- nunez 3y agoGreat explanation. Thanks, Julia!
- PeterWhittaker 3y agoI just reread my take on branches and relearned some stuff I’d forgotten: https://peter-whittaker.com/obligatory-grokking-git-post https://peter-whittaker.com/obligatory-grokking-git-post Warning, all text, no diagrams....
- rkangel 3y agoGit doesn't have the concept of "main is special", but at least tools like Gitlab have protected branches to stop you screwing up too much. Some concept of "parent" and "child" branches would actually be pretty interesting. You do have to support multiple "parent" branches though for long term support branches.
- samus 3y agoProtecting branches is indeed very important. I make errors all the time when screwing around. It helps enormously being restricted to just messing up one's feature branches. Many other changes can be done via the GUI with PRs and the various kind of controlled merge and rebase strategies they support, like Merge, Rebase + Merge, FF-only Merge, Squash merge, etc.
- cedws 3y agoIt's also a security feature. If you have a repo with a lot of developers working on it, you need to be sure they absolutely cannot slip in code with nobody noticing, or trigger CI/CD and compromise build secrets or even production.
- andrybak 3y ago> Git doesn't have the concept of "main is special" Technically, there is special handling for both "master" and "main" in Git in fairly obvious, but I'd argue in a not very important way. When you merge two regular branches, the commit message is `Merge branch 'source' into destination`. But not if destination is `master` or `main` – the `into ...` part is omitted for those merge commits. But this is just for backward compatibility. Git is very conservative in changing such user facing behavior as generated merge commit messages. To get Git to treat `master` and `main` truly without special handling, set empty value to config option `merge.suppressDest` [1]: $ git config merge.suppressDest "" `master` is also used as the default name for the default branch in newly created repositories. See option `--initial-branch` of `git init` and config variable `init.defaultBranch` [2] to override. Git for Windows, for example, allows setting the config option in its installer. Source code: For merge commit formatting: https://github.com/git/git/blob/2108fe4a1976f95821e13503fd331f075da398c6/fmt-merge-msg.c#L646-L649 https://github.com/git/git/blob/2108fe4a1976f95821e13503fd33... For default branch naming: https://github.com/git/git/blob/91e2ab1587d8ee18e3d2978f2b7bc250faf5df8f/refs.c#L662-L686 https://github.com/git/git/blob/91e2ab1587d8ee18e3d2978f2b7b... Git for Windows installer suggesting setting `init.defaultBranch`: - https://github.com/git-for-windows/build-extra/blob/586c46eca4c47dc9d596d0465c1f06451f2ea8c8/installer/install.iss#L2026-L2053 https://github.com/git-for-windows/build-extra/blob/586c46ec... - https://github.com/git-for-windows/build-extra/blob/586c46eca4c47dc9d596d0465c1f06451f2ea8c8/installer/install.iss#L3219-L3224 https://github.com/git-for-windows/build-extra/blob/586c46ec... Footnotes: [1] https://git-scm.com/docs/git-merge#Documentation/git-merge.txt-mergesuppressDest https://git-scm.com/docs/git-merge#Documentation/git-merge.t... [2] https://git-scm.com/docs/git-init#Documentation/git-init.txt--bltbranch-namegt https://git-scm.com/docs/git-init#Documentation/git-init.txt...
- Sharlin 3y agoBut... If you have a rebase workflow, then `git checkout trunk; git rebase branch` is exactly how you "merge" an offshoot branch into a trunk branch! That's what Github does when you rebase-merge a PR, for example.
- karatinversion 3y agoNo, that’s not right. If you did that, you would need to force push to get the result pushed to the remote.
- Sharlin 3y agoOh, right. So what actually happens is that the offshoot must first be rebased on top of the trunk, and then trunk can be fast-forward merged/rebased (same thing, really) to the offshoot's head.
- ChrisMarshallNY 3y agoThat's an excellent explanation. > “Wrong” models can be super useful. This is used in usability and UX design a lot. Affording mental models that don't reflect the actual code, happens all the time.
- samus 3y agoThis is perfectly fine and the added value of a great application if it can hide the underlying reality completely. With Git, the abstractions are paper-thin at best though. Good UIs can indeed cover up many aspects, but they only work as long as there are no merge or rebase conflicts. To correctly resolve these, the user has to have a precise picture of what is actually going on.
- pvg 3y agoThis is used in usability and UX design a lot. It's the fundamental thing that makes UI work. I've always liked the title of Brenda Laurel's book - Computers as Theatre
- informalo 3y ago> You do need to explicitly specify the other branch when merging or rebasing or making a pull request (like git rebase main), because git doesn’t know what branch you think your offshoot is based on. I think a big issue with the presented intuition is that it's limited to wanting to merge the base/trunk/main branch into your feature branch. However, sometimes you want to merge a feature branch into another feature branch. With this in mind, you can form a better intuition, imo, where it's absolutely clear that you have to specify what branch you want to merge into another one.
- mtnygard 3y agoI have found that git makes a lot more sense if you reverse the mental model of lineage. People think about a lineage going forward. But a more useful way to think is in terms of backward pointers. A commit points to it's parent(s). Since a branch is just a commit ID, you can follow the parent links backwards to find the whole history of that branch. So a "branch point" is just where two chains of parent links converge. The special part are merge commits. Those have multiple parents, indicating that two histories fused into one.
- layer8 3y agoThe issue is that if you consider a branch to be what is really the history of the branch tip, then a branch is not just the part starting from the last join with another branch. Instead it is some directed path through the commit DAG, a path that in general can’t be reconstructed from the information Git keeps. If, for example, you have a structure like | o / \ o o A | | B o o \ / o / \ o o C | | D o o \ / o | then conceptually the path CA might be one branch and DB the other branch (or alternatively, CB and DA). But this is not something that is represented in Git’s model.
- lifeisstillgood 3y agoJust to go off on a tangent - that's a pretty neat diagram for a throw away comment. was that just careful spacing in the HN textbox or did you use a tool - which one ? :-)
- grodriguez100 3y ago“Text after a blank line that is indented by two or more spaces is reproduced verbatim. (This is intended for code.)” Looks like this also switches to a monospaced font, which makes it easier to draw ASCII art. This should be rendered using a monospaced font. _____ \ / \ / O
- mountainboy 3y ago
- keybored 3y agoLately I’ve wanted branches (heads) to have a corresponding tail which points to the base commit that the branch sits on top of (like the commit on `main` when you created the branch).[1] Because branches get rebased all the time and eventually you have six commits out in the Æther somewhere and you have to think twice about where it even starts. And yeah you can probably think for a few seconds and recall that you have worked with John and not Jimmy on this branch so the seventh commit backwards that belongs to Jimmy must be the commit base. Or Git can tell you that the seventh commit belongs to `main` already. But why should you have to expend any effort? You can optionally include the base commit when you send out “patches” to a mailing list.[2] Because it might not have been obvious that you based your changes on: - The latest release - The main development branch - Some integration branch (probably an error) You also need to keep the “base” in mind when you use `git range-diff` because that tool takes two ranges lik `main..previous` and `main..current`. And sometimes you can rely on just using `main..` and letting Git figure it out but in my experience passing an explicit value sometimes works better. `git range-diff` is a super-cool but perhaps niche tool. But you basically have to use it on review round number 2 and higher when you are sending changes to the Git project. [1] This has been discussed before and there was a patch series that implemented it. But that was basically a POC and done in the spirit of “this is useless IMO but here’s how you could do it”... and the implementation didn’t factor in all the shenanigans that you can do with `reset` and `rebase` so it couldn’t have been merged as-is. (Although to be fair: the bar was not set to work perfectly with any kind of branch reset etc., which I suspect is impossible in any case.) [2] Patches after all are just commit messages plus the patches themselves and don’t tell you what they are based on.
- Snarwin 3y agoIt looks like this is what git merge-base --fork-point is supposed to do, although according to the docs it is not 100% reliable.
- keybored 3y agoBased on all the discussions I’ve seen I think it’s impossible to programmatically find the “base” in general. Maybe it’s possible for most cases though.
- chatmasta 3y agoWe're teaching Git wrong. Most of the common confusion is due to people learning from the porcelain down to the plumbing, when it should be the other way around. If you limit your mental model to the plumbing, there's generally only one outcome that you want, but there are a dozen ways to get there from the porcelain. You can choose whichever one you prefer. But if you start from one of those dozen ways, they could each lead to a different outcome than you expected. I'm forever grateful for one of my early internships, where a guy from GitHub visited the office and gave us a one day workshop on Git. He started from the internals and explained how Git models your codebase. (He's also the one who introduced me to the idea of plumbing vs. porcelain.) Then once we had a common language, teaching the porcelain was a matter of starting from the plumbing and working upwards, rather than the other way around. Another invaluable resource in learning Git is this interactive tutorial [0], which renders a tree diagram of start state and desired end state and makes you write the commands (for which there are often many options!) to get to that end state. This reinforces the idea that the best way of planning Git commands is to first visualize the end state you want, and then reason about how to get there. Also: RTFM! Not just once. Go back to it. You'll learn something new every time. The docs [1] are really good. [0] https://learngitbranching.js.org/ https://learngitbranching.js.org/ [1] https://git-scm.com/docs https://git-scm.com/docs
- deleted 3y ago[deleted]
- spenrose 3y agoIf you learned from this (excellent) piece, I recommend that you buy and work through https://leanpub.com/learngitthehardway https://leanpub.com/learngitthehardway . It will take less than a day, and you'll have a much stronger foundation for a core tool.
- riperoni 3y agoWhile the explanation is right in some sense, it misses a few points. Branches are pointers to a commit and that pointer is refreshed when a new commit is created. One could say they are a wandering tag (without explaining a tag for now). The actual chain of commits that represent what we see as branch comes from the commits themselves. Those commits point back to their parent commit. And then one can see why no branch has any special meaning: It is a chain of related commits with a named entrypoint. Once you delete a branch (i.e. the named wandering pointer to a commit), you cannot identify a branch as such anymore. It is just a chain of related commits without a named label now. And nothing besides the name distinguished the branch from other commit chains before. The master/dev/release branches are then a convention to keep an updated commit pointer on the chain of commits containing changes of interest.
- jansan 3y agoThis was the most useful piece of information that I have ever read about Git. But what happens if you merge branch A into beanch B? A and B will both contain the commits of A, but in B there may be commits of B between the commits that were merged. Do the same commits of A then have different parents depending on which branch they are on?
- paulddraper 3y agoMerging branch A into branch B does two things: 1. Create a new merge commit with two parents: the commit pointed to by A and the commit pointed to by B. 2. Set branch B to point at the new merge commit. This is a non-linear history; when comparing some commits there isn't a "before" or "after."
- hackernews1134 3y agoIf I checkout the merge commit and then do a ‘git log -n 5’, which parent pointer is followed to show the previous commit logs? A or B or Both / all if it is more than a 2-way merge?
- 3y ago
- gtirloni 3y agoSome of Julia's tweets started to get suffixed with "I don't want advice about this". It must have reached unacceptable levels.
- cube2222 3y agoThere is a very good article by GitHub: https://github.blog/2020-12-17-commits-are-snapshots-not-diffs/ https://github.blog/2020-12-17-commits-are-snapshots-not-dif... TLDR: Think of commits as snapshots, not diffs, and you'll be fine.
- MauranKilom 3y agoI don't use git at work, but in my private hobby projects my friends usually get mad when they watch me juggle changes and branch pointers with git reset --hard and git stash... How do you undo a merge that you didn't mean to do/did wrongly? git reset --hard <last commit before merge> Have some cosmetic fixups on your local branch that really should go into main (or a separate branch) first before merging a bigger feature? git stash git checkout main git stash apply By thinking about branches as pointers, the commit graph existing independently, and stashes just being temporary commits, I feel I'm working much more directly with the underlying abstraction. Yes, git has commands for specific combinations of actions, but for an occasional user it's harder to remember every such command and which arguments and flags to pass in which order. It's either "look through documentation until you find graph diagrams illustrating what will happen for this order of arguments and flags" or "use the primitives 'move branch pointer', 'commit to branch', 'hold these changes for a second' for obtaining the commit tree you actually want. Knowing that the reflog exists also makes this insane-sounding working mode pretty non-scary. And yes, some operations (e.g. cherry-pick) you just need to do the "real" way. (My git stash obsession is most likely just damage from years of using Perforce, which doesn't have a modified/staged distinction. The only way to commit only part of a changed file is via the equivalent of stash -> [restore half the file] -> commit -> stash pop.) Prepares to be crucified...
- globular-toast 3y ago"Undo" is usually more like `git reset --hard HEAD@{1}`, ie. using the reflog. Nothing wrong with this at all. Only people who don't understand and/or are scared of git don't like it. You could also use cherry-pick to "donate" commits to other branches, instead of stash, of course. Magit has some great extra abstractions for this.
- hotnfresh 3y agoYou can check out multiple branches in different directories from a single git repo. This saves me a lot of what used to be stashing.
- bshacklett 3y ago
- bloopernova 3y agotl;dr Please ignore, just me working through a Python+pygit2 problem. I solved it in a grandchild comment. I had so much trouble trying to map my intuited/mental model of git onto pygit2 that I gave up and just used the git module. I wanted to automate a fairly simple thing in Python as opposed to bash+commands. My reasoning being that I wanted to do it "right" and be a Big Programmer Real Boy(tm). I just wanted to create a branch remotely in Github, pull the repo, and checkout the new branch. I got stuck going in circles trying to figure out why I was always left in detached HEAD state because I didn't understand exactly what git was doing during a checkout. # repo has already been pulled if os.path.exists(repo_path): local_repo = git.Repo(path=repo_path) self.log.debug(f"current branch: {local_repo.active_branch.name}") local_repo.git.checkout(branch_name) That's super easy and is much the same as running the commands in the shell or in a bash script. Of course, I've lost my poor implementation using pygit2, so I'll add that later if I find it. Thankfully there's a good discussion surrounding the issue I encountered in this excellent "roll your own git in Python", which doesn't use pygit2, but the concepts are the same: https://www.leshenko.net/p/ugit/#checkout-switch-branches https://www.leshenko.net/p/ugit/#checkout-switch-branches
- bloopernova 3y agoThis isn't asking someone else to make this work, it's more of a caution to convince folks like me to just use "import git" rather than pygit2: So something like this was what I expected to work, but leaves the repo in detached head state: import pygit2 def checkout_branch(path, branch_name): repo = pygit2.Repository(path) branch_ref = repo.lookup_reference(f"refs/remotes/origin/{branch_name}") print(f"{branch_ref.name}") repo.checkout(branch_ref) The branch_ref.name prints "refs/remotes/origin/test" but git status says "HEAD detached at origin/test" So I'm probably feeding the wrong thing into repo.checkout, but I'm honestly not sure what else it should be. Funnily enough, git itself tries to do the right thing if pulled in a detached head state: From https://github.com/testorg/example * [new branch] test -> origin/test You are not currently on a branch. Please specify which branch you want to merge with. See git-pull(1) for details. git pull <remote> <branch>
- parasti 3y agoThe article goes in the right direction, but from a weird starting point. Saying things like "a branch contains the entire history" just adds to the general confusion about Git. Git does not have branches. Sure, Git emulates branches to appear familiar and intuitive, but it is actually counterproductive to use that as a starting point to explain how Git works. Git manages a graph of commits and some of those commits need human readable labels. That's it. The only thing that contains the entire history is the commit graph itself.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- BlueTemplar 3y agoAnother way to think about merging and patches : https://jneem.github.io/merging/ https://jneem.github.io/merging/
- justincredible 3y agoAnother situation where the intuition breaks is that a repo can have branches without a common base (i.e., disconnected graph). Definitely unusual, but sometimes I want to move a folder between repos while preserving the commit history of the folder[0]. [0] https://stackoverflow.com/questions/41811986/git-move-directory-to-another-repository-while-keeping-the-history https://stackoverflow.com/questions/41811986/git-move-direct...
- intrepidsoldier 3y agoAnything about Git reminds me of this: https://youtu.be/EReooAZoMO0?si=sHqcYsf8v6LyWLAx https://youtu.be/EReooAZoMO0?si=sHqcYsf8v6LyWLAx
- chihuahua 3y agoGiven how many smart people are confused by Git, and how many times Git's behavior needs to be explained in a way that often raises as many questions as it answers, it seems to indicate that Git's model is not at all intuitive and doesn't map well to how people generally use it to get work done. These are all people who have no problem understanding all kinds of other technologies and building complex systems from them. It's not quite in "a monad is just a monoid in the category of endofunctors" territory, but when this many smart people have difficulty understanding something, I think Git is to blame, not the people.
- CuriousCosmic 3y agoI have to serious ask. Of the people who have issues with using or understanding git, how many of them have actually read the docs? Git is by no means perfect but the development community is great and there is a massive focus on improving the project and making things more approachable and intuitive. And because of that, git actually has really solid, coherent documentation with easily digestible tutorials and guides for all the things you need to do. So it always hurts me when I see people ranting and raving about how awful git is, how it can't do x, or how it doesn't make sense how it works but then you send them the guide or tutorial hosted on the git-scm website and suddenly it makes sense. Not to be beating the RTFM horse but RTFM guys.
- chihuahua 3y agoWhenever I read the Git docs, after a while I start thinking "this is all very well and good, but it doesn't seem to be related to what I'm trying to do to get my work done (usually fairly basic things)" Or I have read a bunch of pages on the git-scm site, and I'm thinking "oh yes it all makes sense now." Then I'm trying to do something in the real world, and I get bizarre messages and conflicts that don't make any sense. Or I made a mistake and want to undo it, and end up in some crazy situation. The Documentation doesn't seem to help in anything but an ideal textbook scenario with no mistakes and complications.
- gitanovic 3y agoI think that one way to "easily" understand the syntax of git is to remember that when you perform a command you "always" modify the current branch for example: git merge my-branch will merge my-branch into the current one while git rebase my-branch will rebase current one on top of my-branch
- Vinnl 3y agoYears ago I wrote this dynamic tutorial that visualises branches as you read: https://agripongit.vincenttunru.com https://agripongit.vincenttunru.com It's aimed at folks who know how to use `git add` and `git commit`, and would like to spend 15 minutes to form a mental model to help them understand what's going on. In case it's useful to someone.
- k__ 3y agoThat article would have been a lot better if it showed illustrations for the "right" mental model too.
- taberiand 3y agoThe right mental model is to realise the 'main' branch is only special by convention - git doesn't actually treat it differently from any other branch. All of the confusion expressed in the article stems from a misunderstanding that main should work in some special way. Of course every branch's history goes all the way back to root and not to some arbitrary common commit of another branch like 'main'. Of course rebase and merge can work "backwards" from main onto some branch (because it's not "backwards" because main is not special - it just isn't done much in practice because keeping main straight helps with collaboration) Furthermore, by realising that main isn't inherently special, it becomes obvious that the actions can be done between any two branches as needed. The right mental model is - it's just commits, all the way down.
- k__ 3y ago"All of the confusion expressed in the article stems from a misunderstanding that main should work in some special way." I didn't have that impression when reading that article. To me it seems that the confusion comes from thinking in actual branches, and not from thinking anything special about main.
- taberiand 3y agoThey're only thought of as actual branches (off of main) if you're also thinking of main as a trunk that is in some way special or different.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- why-el 3y agoI've learned only one constant with git in my years as a programmer: master your own employer's git use cases, and pray to god for three things: 1. you don't change places often and thus git patterns. 2. you don't accidentally ship and commit a multi-GB file to your remote. 3. you don't change the git process on yourself and your colleagues without an extremely solid reason. Document your chosen git patterns, even in 2023.
- tsbx 3y agoI always get back to this page when trying to understand/show how git works under the hood: https://eagain.net/articles/git-for-computer-scientists/ https://eagain.net/articles/git-for-computer-scientists/ It summarizes fundamentals clearly.
- deleted 3y ago[deleted]
- asylteltine 3y agoMercurial is SO much better than git especially how it works at meta. I hate git.
- Aeolun 3y agoReading this it seems to me that it should be incredibly easy to create an alternative version of the git client that stores the lineage per branch and can inform people if they’re doing things they probably shouldn’t.