3 ms·
Let me just start by saying that while gitless seems fine, it tries to hide the index and thus encourages bad habits in git users. The index is by far one of t
by chousuke 10y ago
Let me just start by saying that while gitless seems fine, it tries to hide the index and thus encourages bad habits in git users.
The index is by far one of the best features git has in comparison to other VCS, and trying to hide it because it can be confusing to users is doing them a disservice.
EDIT: editing this to expand on why I think the index is essential:
Being able to use the VCS tool to fashion a commit separately from what is in the worktree allows you to create changesets that make sense, instead of them being "this is what happened". Exact history is not interesting, it is the logical progression of the codebase (via changes applied to it) which really matters.
Furthermore, when resolving conflicts, the index is extremely useful because you can work through a conflict (which often can span multiple files) piece-by-piece and easily tell whether you've already fixed everything, run diffs on what's resolved and what isn't, etc. I find myself missing the index whenever I need to do anything nontrivial with other VCS (which is most often Subversion)
I've seen some people argue that they don't want to commit something that has not been tested, but I don't understand this argument. Why would you test something that isn't committed? Committing (or even pushing) something does not mean the code is instantly in production, but it means you have an unambiguous way to refer to what is being tested, instead of whatever state your worktree and system happened to be in. How could you be sure you're really testing what you will be committing?
Certainly, creating separate commits after-the-fact can cause commits where the tests don't pass, but it's up to you to decide whether the merge points are what should be tested, or each individual changeset.
Let's go through that list
- git checkout does one thing: it updates your worktree to match whatever you want to check out, be that a commit, a branch (which actually is just a named commit) or a file in a branch. Why is this difficult for beginners, and how would you refactor/name the operations so that they make sense?
- I'm not sure what you mean with context-dependency. Obviously it's context-dependent in that your worktree and repository may be in a state where certain commands do different things eg. because they have the current checked out branch as an implicit parameter. I don't think it's at all different from most other VCS
- I'm not sure I'm convinced by the article's argument that branch switching is hard, but I guess I'll grant that.
- Huh. I don't use stash that often, so this is a maybe. Teach people to use stash apply instead?
- git rm --cached is weird, but mostly because git can't choose just one thing to call the index.
- You can never accidentally destroy history with a rebase. Nothing short of manually wiping files destroys history in git once something has been committed. I don't really see why detached heads would be a problem (just create a branch?) and if you force push, you're basically telling git "I know what I'm doing, shut up" in which case the tool doesn't assume you're an idiot and will do what you want. You can't call it bad UI when you explicitly have to use a --force flag to do potentially destructive things. Not being able to do it at all is worse.
Really though, other than minor gripes with terminology and maybe sometimes confusing command line switches, what is a good (hypothetical) UI for git that doesn't just ignore all the good things?
- twic 10y ago> The index is by far one of the best features git has in comparison to other VCS, and trying to hide it because it can be confusing to users is doing them a disservice. I can't disagree more. The index is entirely unnecessary, as umpty thousands of happy Mercurial users can testify. > Being able to use the VCS tool to fashion a commit separately from what is in the worktree allows you to ... record states which never existed, and haven't been tested. It's an antipattern. If you are doing this a lot, you are doing development wrong. In the rare occasions where you do want to do it, Gitless and Mercurial, like every other source control tool, give you a way to fine-tune the set of files which go into the commit. They don't need an index to do it. > Furthermore, when resolving conflicts, the index is extremely useful because you can work through a conflict (which often can span multiple files) piece-by-piece and easily tell whether you've already fixed everything, run diffs on what's resolved and what isn't, etc. Again, you don't need the index for this, you need to track conflict state. As Mercurial does: https://www.mercurial-scm.org/wiki/TutorialConflict https://www.mercurial-scm.org/wiki/TutorialConflict > I've seen some people argue that they don't want to commit something that has not been tested, but I don't understand this argument. Why would you test something that isn't committed? This is a very interesting perspective! It doesn't immediately sound immensely practical, though. Say i want to test a fraction of the current working tree's state; i commit, and then ... what? Create a fresh clone of that state somewhere so that i can run tests on it?
- chousuke 10y agoSure you can make do without the index, that doesn't mean it's better not to have it. I personally don't feel comfortable with mercurial, but that may be because I don't understand it. It's been a long time since I last touched it, but I remember thinking that the way it does branches was just needlessly complicated and cumbersome. Why does closing a branch even need to be a thing? > you don't need the index for this, you need to track conflict state This is what the index does. You don't need the index in mercurial, because you have something that is like the index, but not called the index. Maybe the UI is better because "add" is called resolve, but that is really just an alias away. > and then ... what? Then you push it to remote somewhere and a CI system runs tests for you. Maybe you can do something productive in the meantime. If you're just testing locally, then there's little difference, but I would still prefer testing a committed state, knowing it's safe in the repository and I can't clobber it afterwards.