3 ms·
> In particular, you can't check out a bookmark, you can only check out commits. That's because "branches" in git are an imaginary concept, they are simply a l
by epolanski 1y ago
> In particular, you can't check out a bookmark, you can only check out commits.
That's because "branches" in git are an imaginary concept, they are simply a label you give to a certain commit, nothing else, nothing more.
Moreover, in git this is further complicated by the fact that you may have branches with the same identical name on different environments (your local and remotes). So you can have, by any means, 4 `feat/foo` branches all being the "right" `feat/foo`, and you need to decide which one is the right one (we tend to default to some origin, but what if you have local work that is ahead of origin? maybe on two different computers? Meanwhile your branch is on a fork of a different origin. Git branches do nothing but complicate a simpler model where what matters is the commit, history and diff, yet we fixate on label names which are just conveniences).
At the end of the day branches do nothing but add complexity, I much prefer the jj model, bookmarks are just _local_ names you give to some edit, you move the bookmark manually, and it _may_ point to a git branch just to preserve the git backend.
- MrJohz 1y agoThe problem is that branches _aren't_ an imaginary concept in git. The easiest way to see this is by looking at the difference between `git checkout master` and `git checkout ae596fe`. The first one checks out a branch, but the second one checks out a headless commit. I can still do many of the same operations in both states (for example, I can create new commits based on the current one), but how the repository changes will differ depending on what I've got checked out. I agree with you that this is mostly unnecessary complexity — branches being anonymous is one of the big reasons I like jj, and why I think it's so useful to people just getting started with version control, because it is a simpler conceptual model. But it's not correct to say that branches in git are imaginary.
- tsimionescu 1y ago> That's because "branches" in git are an imaginary concept, they are simply a label you give to a certain commit, nothing else, nothing more. They're really not. The whole Git ecosystem makes a very clear distinction between branches and tags, even though they are virtually the same thing in the underlying data model. For example, if you checked out a branch and then do a git commit, the branch name tag will be automatically moved to the new commit. Conversely, if you checked out a tag (or a random commit that is not the head of a branch) and then run git commit, the new commit will not get any tag. Another example is `git rebase`, whose semantics only make sense if you consider that branch names refer to branches, not just to their latest commits, since they often modify many children of those branches. > Moreover, in git this is further complicated by the fact that you may have branches with the same identical name on different environments (your local and remotes). This is presented as more complicated than it is. If you are working with multiple remotes, you may end up in these complex situations, true. But Git is pretty clear about the names and identities of each of these. You have the local branch, `feat/foo`, which typically has as a default upstream the remote branch named `feat/foo` on a remote called `origin`; the local copy of that branch is the tracking branch called `origin/feat/foo`. If you have other remotes `remote1` and `remote2`, the tracking branches of those are called `remote1/feat/foo` and `remote2/feat/foo`. You will never want to commit directly to any of these tracking branches - instead, you'll create either separate local branches with each as an upstream(`feat/foo-remote1`, `feat/foo-remote2` - if you want different commits for each remote), or directly push from `feat/foo` to all of them if the intent is to keep them in sync (`git push feat/foo:remote1/feat/foo` or similar).
- epolanski 1y ago> the branch name tag will be automatically moved to the new commit On your specific repository.
- tsimionescu 1y agoOf course, where else? All git operations only affect local branches, except git push.