3 ms·
As a git user "not by choice" (my preference going for mercurial every single day), I never understood why git needs this distinction between bare/non-bare (or
by ezst 1y ago
As a git user "not by choice" (my preference going for mercurial every single day), I never understood why git needs this distinction between bare/non-bare (or commit vs staging for that matter). Seems like yet another leaky abstraction/bad design choice.
- skydhash 1y agoA repo is as database containing a tree of commits. Then you got the concept of branch, which points to a specific commit. Then there's the special pointer HEAD which is the latest commit for the current worktree. When you checkout (now switch) a branch, HEAD is now the same as the branch (they point to the same commit). When you do operation like commit, reset, reset,... both the head and the branch are updated. So if a remote node tries to update the local node via a push on its end, that would mess up the local worktree. So you create a bare repo instead which can't contain a local worktree. Note: A worktree is computed from the initial commit to the commit currently identified by HEAD by following the parent information on each commit. The staging area is like a stored snapshot of what you would like to commit. You can always create patch between HEAD and the worktree, edit it, and then save the patch as the commit, then apply the leftover to the worktree. The staging just make that easier. It's a WIP patch for the next commit.
- seba_dos1 1y ago> When you checkout (now switch) a branch, HEAD is now the same as the branch (they point to the same commit). Actually, HEAD now points to that branch, which in turn points to the commit. It's a different state than when HEAD points directly to the same commit (called "detached HEAD" in Git's terminology) where this issue doesn't happen as you're not on a branch at all. It's a subtle, but important distinction when trying to understand what happens under the hood there.
- skydhash 1y agoYou're right. I was trying to simplify.
- DrinkyBird 1y agoMercurial has no distinction between a bare repo and a non-bare repo: any repo can have a working copy or not. You can check out a working copy with `hg update somerevision`, or get rid of it with `hg update null`. You can push to a repo with a working copy, if you like; nothing will happen to that working copy unless you run `hg update`. Since you don’t need a working copy on the server’s repo, you never run `hg update` on it, and it’s effectively what git calls a bare repository.
- ezst 1y agoSo, exactly as DrinkyBird said: I still don't see a good reason for this distinction to exist, what's in the repo's history and in its working directory are orthogonal concepts that are tied together by a bad UX for no apparent gain.
- rester324 1y agoYeah, I am in the same boat. My files are either non-staged or committed about 99.99% of the time. For me the concept of staging is completely useless
- mbork_pl 1y agoStaging is immensely useful in more than one case. Case one: WiP on a branch, code is pretty stable, but I want to do some experiments which will likely be deleted. I stage everything and then make (unstaged) changes which I can then undo with two keystrokes. Case two: I'm reviewing a complex PR, so I first merge it with --no-commit, then unstage everything and then stage chunks (or even individual lines) I have already reviewed. Case three: I was coding in the state of flow and now I have a lot of changes I want to commit, but I want to separate them into several atomic commits. I stage the first batch of changes, commit, then stage another, commit, etc. There are probably more, but these three alone are worth having the staging area.
- ezst 1y agoCase one: you don't need staging. You can stash, or just commit and checkout HEAD^ Case two: you don't need staging. You can stash, and then unstash incrementally (I would be shocked if git doesn't have the equivalent of `hg unshelve --interactive` and its keyboard friendly TUI) Case three: you don't need staging. You can just edit/amend the series (rebase --interactive I believe you guys call that). That is to say, all that you want to put in your stash, you could commit directly to the DAG, and edit to your convenience, with the regular history-rewriting tools already at your disposal. And the off-DAG stuff can be handled by stash (and even there, a normal commit that you would rebase to its destination would perfectly do). And what I described is incidentally what https://github.com/jj-vcs/jj https://github.com/jj-vcs/jj does, which can be pretty-well described as "taking the best of all major VCSes"
- ezst 1y agoThough I wasn't trying to say that there is no need for staging-based workflows, I was just saying that there is nothing in terms of convenience or capabilities that the staging area does that can't be achieved with just regular commits and amending/rewriting. The immediate response from many git users when confronted to alternative VCSes is "well, it doesn't have a staging area, so it's obviously inferior" instead of going with "let's see how differently they approach this problem, and perhaps I will like it/git isn't all perfect after all".
- mamcx 1y agoJujutsu make the interaction sane, and is far more logical than even mercurial (that I love too!)