Live data from Hacker News

Git Branches: Intuition and Reality

jvns.ca

91–100 of 281 posts

Re: Git Branches: Intuition and Reality

#91

Earlier quoted context omitted.

> moving files isn't stored in git is there an intuitive and enlightening explanation as to why it is this way?

Git stores snapshots and that’s it. The whole tree, not per-file. As to why Linus doesn’t like storing file moves: https://public-inbox.org/git/Pine.LNX.4.58.0504150753440.721...

It's kind of funny to see Linus browbeaten other people into submission regardless of him being right or not, while claiming "I am always right".

A few counter points:

- `hg` has `cp`, and I believe both Meta and Google's internal systems have that; - git has `mv`, which was added later, but it is really janky and git would forget files are moved which I think it is because git doesn't try to track that, likely because of the philosophy here; - as for storing file moves - nobody said you *have* to use this information, but you can certainly use this information to help with things.

The whole thread is an interesting read though and I will try going through it someday - maybe doing that would change my mind.

Re: Git Branches: Intuition and Reality

#92
post #75
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

Unless you are superhuman and never make mistaeks, you should put "git rebase" (with and without -i) on top of your list of things to learn.

Let us also hope they do a git diff before pushing changes.

Re: Git Branches: Intuition and Reality

#93
post #71

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…

This 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?

[deleted]

Re: Git Branches: Intuition and Reality

#94
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

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

It's `git switch [-c]` nowadays.

Re: Git Branches: Intuition and Reality

#95
post #54

Earlier quoted context omitted.

BitKeeper already did it.

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

git log has --follow but unfortunately it only works when spefying a single file and not e.g. a whole directory.

Re: Git Branches: Intuition and Reality

#96
post #71

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…

This 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?

I keep repeating this every time someone talks about git and finds something weird or doesn't get branches, so I'm really glad your parent mentioned it as well and I know there's someone else out there that "gets" that:

    In git it's all just labels/pointers
It's not useful at all to think about branches as the user sees them as "things" of their own. Branches don't "have" anything. Branches in that sense are just convenient labels.

Of course actual "branches" in the commit tree exist whether you label them or not. Until `git` does a garbage collection and gets rid of anything that doesn't have a pointer ultimately leading to it - something that a human would understand aka branch/tag. And that's why we call these labels "branches" as well but it's actually one word for two things here. The actual tree branch and the label that's called branch.

And a branch and a tag are basically the same exact thing underneath, just a file in the `.git` directory somewhere that contains a commit hash. All the meaning and differentiation of branch or tag is just in the human brain and how we and our tools treat them. Such as if you look at a particular commit in your tool of choice, it will tell you which branch it's part of. To create a branch you can literally just create a thousand randomly named files in the right part of the `.git` directory containing the same commit hash and suddenly this commit "is on all those branches". That's what git does and why creating a branch in git is so super fast.

Re: Git Branches: Intuition and Reality

#97

tl;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 c…

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

Re: Git Branches: Intuition and Reality

#98

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

[deleted]

Re: Git Branches: Intuition and Reality

#99
post #71

Earlier quoted context omitted.

This 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?

I keep repeating this every time someone talks about git and finds something weird or doesn't get branches, so I'm really glad your parent mentioned it as well and I know there's someone else out there that "gets" that: In git it's all just labels/pointers It's not useful at all to think about branches as the user sees them as "things" of their own. Branches don't "have" anything. Branches in that sense are just conv…

To make things more complicated, the word "tag" is also overloaded. It can either be just a reference (in git lingo, a "ref") to a commit - just like a branch, only differing from it in how the tools treat it; but they can also be "annotated tags" which are pointing to a special tag object which contains some metadata and only then points to a specific commit (or other kind of object...) :)

Re: Git Branches: Intuition and Reality

#100
post #18

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

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

There’s some special handling for FETCH_HEAD too (i.e. which branch on a remote is considered the default).
Post reply on HN