Live data from Hacker News

Git Branches: Intuition and Reality

jvns.ca

221–230 of 281 posts

Re: Git Branches: Intuition and Reality

#221
post #200

While 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 bran…

> 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). A good name for these "wandering tags" would be "heads", since it's what git calls them internally (for instance, when not packed, they're stored at the "refs/heads/" path in the repository). This also exposes a distinction between a "branch" and it…

So would it be correct to say that 'heads' are the LEAVES of the commits-tree?

Or are there such leaves which are not considered 'heads'?

Re: Git Branches: Intuition and Reality

#222
post #85
post #30

Earlier quoted context omitted.

No, 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…

> `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.

Well along those same lines, making a commit doesn't move HEAD, it's still pointing at the same branchname as before.

  cat .git/HEAD

Re: Git Branches: Intuition and Reality

#223
post #203
post #167

Earlier quoted context omitted.

> mismatch to the intuitive “a named lineage in the DAG” conception of branches Once more, that conception may be intuitive but it is wrong . A branch is emphatically NOT a line through the DAG, it's the whole DAG. There simply is no single list of patches to apply to get from one commit to another, even if both were at some point heads of the same branch, and even if one is an ancestor of the other. And the reason i…

I don’t see what is wrong. Branches in that conception are paths through the DAG. One would like to annotate such paths with names, and have those names automatically apply by default when adding a commit to the end of such a path. This has nothing to do with lists of patches. Nevertheless, for any given path, it is always possible to compute a list of patches that would match that path. Just compute the diffs betwee…

The problem is that the thing that Git calls a branch does not identify a specific path. Look at OP's example again: if you conceptualize branches as paths, then CA/DB and CB/DA are distinct ways to divide that graph into branches. But in Git there is no way to represent that distinction (at least, not as branches).

Re: Git Branches: Intuition and Reality

#224

Earlier quoted context omitted.

I 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 guide…

I've read the docs. Too much explanation of command line flags, not enough practical examples. It is thorough though.

Including the git user manual [1] and the git book [2]? People tend to skip over those and go straight to the reference/manpages.

1. https://git-scm.com/docs/user-manual

2. https://git-scm.com/book/en/v2

Re: Git Branches: Intuition and Reality

#225
post #203
post #167

Earlier quoted context omitted.

> mismatch to the intuitive “a named lineage in the DAG” conception of branches Once more, that conception may be intuitive but it is wrong . A branch is emphatically NOT a line through the DAG, it's the whole DAG. There simply is no single list of patches to apply to get from one commit to another, even if both were at some point heads of the same branch, and even if one is an ancestor of the other. And the reason i…

I don’t see what is wrong. Branches in that conception are paths through the DAG. One would like to annotate such paths with names, and have those names automatically apply by default when adding a commit to the end of such a path. This has nothing to do with lists of patches. Nevertheless, for any given path, it is always possible to compute a list of patches that would match that path. Just compute the diffs betwee…

No! No, they are not. This is a mistake you are making, and I'm trying (vainly, maybe) to correct it.

If you have a branched structure like that, and dump each commit as a patch, and try to trace a "path through the DAG" by applying those patches, you will find that they don't apply after the first merge commit. There is no single list of patches, because that's not the structure of the history. The merge commit "patch" must be a different delta depending on where you came from.

Re: Git Branches: Intuition and Reality

#226
post #216

Earlier quoted context omitted.

Leaning into the tree metaphor (and following the precedent of other version control systems), git should have used the term trunk instead of master or main .

By following this metaphor, a trunk would be the original commit, whereas branches are the tree branch tips.

And consider that because every folder can have its own .git subfolder, we can have several paralle trunks/repositories at the same time, meaning we have a forest.

I haven't really seen specific guidelines as to when and why should anyone start a new repo. Are there some? Or is "mono-repo" the best solution, and when and for whom. Surely we need more than one git-repo in the whole world?!

Re: Git Branches: Intuition and Reality

#227

Earlier quoted context omitted.

This 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.na…

Ha, and of course just messing around gets me something that actually works. There always seems to be just one more stackoverflow thread to read that has the real answer: https://stackoverflow.com/questions/68435607/how-to-clone-ma... (found via Kagi which I wasn't using before, and the search "pygit2 detached head") def checkout_branch(path, branch_name): repo = pygit2.Repository(path) main_branch = repo.lookup_bran…

> I wish there was a pair programmer AI that you had to explain stuff to. That would enable the "by explaining it, I solved it" phenomenon.

It's called rubber duck debugging, named for having an actual rubber duck at your desk you'd talk to.

Re: Git Branches: Intuition and Reality

#228
post #200

Earlier quoted context omitted.

> 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). A good name for these "wandering tags" would be "heads", since it's what git calls them internally (for instance, when not packed, they're stored at the "refs/heads/" path in the repository). This also exposes a distinction between a "branch" and it…

So would it be correct to say that 'heads' are the LEAVES of the commits-tree? Or are there such leaves which are not considered 'heads'?

No. There are leaves that aren't heads (for example, after you delete a branch, the old commits just lie around until someone deliberately cleans them up), and there are heads that arent' leaves (for example if you branch a new feature branch from main. The feature branch brances off of main, so main is not a leaf anymore)

Re: Git Branches: Intuition and Reality

#229
post #8

A 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…

This has resulted in a feature not in VCSs that do track renames: using matching lines, git blame can track changes across files that were combined in a commit, where others would record half the lines as being a rename from one file and the other half as new lines (if you even thought to do it like that when making the commit; more likely the whole file would be tracked as new).

Re: Git Branches: Intuition and Reality

#230
post #10
post #3

I cannot be the only one that gets away with only knowing: git pull git merge x git checkout [-b] foo git commit git push

protip: If you want to switch branch you can now use "git switch [-c] foo". If you want to restore files you can do "git restore .". Basically you can stop using checkout. *edit*: fixed switch branch creation parameter.

Until it's actually removed, muscle memory will keep me using checkout.
Post reply on HN