UX design notes #93
Replies: 6 comments 12 replies
-
Thanks a lot for sharing, these thoughts are super valuable to me as I haven't thought about most of these in detail just yet. As a funny side-note: When reading about these similar sounding subcommands even as a somewhat seasoned user of the As a general idea, for I am very inspired by tools like Another nice side-effect could be that As you can see for I hope you will be able to stay around as I would be glad to involve you/ask for feedback on first versions of actual user facing tooling - this will most certainly make them much better from the start. Thanks a million. |
Beta Was this translation helpful? Give feedback.
-
Some additional comments about diffs: The official There have recently been something of a surge of diffing tools. I found these in particular through HN:
I don't think any of those are appropriate for use in gitoxide, though. Some of them explicitly don't produce patches; but beyond that, they focus on parsing code files in ideal cases (in autochrome's case, Lisp syntax) where the entire file can be parsed into an AST; and they focus on displaying a visual diff, over emitting a machine-readable diff format that can be used by other tools. I think there's room in the rust ecosystem for a standalone diff crate. That crate would:
Also, before this project even got started, it would need a huge battery of test cases. These test cases would mainly be pairs of files for the tool to diff, with some metrics for what the best diff would be. (eg keeping blocks of code together, minimal number of diff lines, etc) |
Beta Was this translation helpful? Give feedback.
-
More UX thoughts: Gix should have first-class support for partial clones. Git has a complicated history on non-full clones. If you only want to download enough data to get the latest commit, Stack Overflow is likely to recommend Problems:
Overall, the Speaking of defaults... subjectively speaking, I don't really think downloading the entire repository every time is a good default. Collectively, it means millions of developers are sending billions of requests to servers to package, compress, and send gigabytes of data that ends up never being read. It's a tremendous waste of energy and server time. Because build systems almost always use the default Individually, it makes the average clone slower than it needs to be, because most developers don't want to spend time figuring out I don't think a last-commit-only partial clone would be a good default either. Some times developers need to compare to previous commits, find who made a change, etc. Trying to make a git diff and getting stalled because Git needs to download blobs would be a poor default experience; especially since developers hate annoyances that don't come from their own decisions. (Also, it can make work impossible if a user finds themselves offline for a prolonged period of time; in practice, I'd expect these cases to be rare) That said, there's probably a middle-ground to be found. Some suggestions:
On the other hand, if really don't want to risk users getting blindsided because they thought they'd had a full clone and they can't fetch anymore, you could do full clones by default, but add a warning message that recommends changing the default in Anyway, that was my take on the subject. Hope it was helpful =) |
Beta Was this translation helpful? Give feedback.
-
I came across this discussion because I'm really excited by gitoxide and decided to poke around :). On the off-chance that y'all didn't see gitless, I recommend checking it out! They did some neat research to identify where git users struggle with git, both mechanically and conceptually—it could be really useful as gitoxide evolves! |
Beta Was this translation helpful? Give feedback.
-
I have been working on an alternative Git CLI for the past two years (it's actually its own VCS but it has a lot of Git interop). That’s pretty much ready; I have used it myself for almost a year and I don’t miss much from Git or Mercurial. Using that instead of starting essentially from scratch (AIUI) with
I will probably try switching from |
Beta Was this translation helpful? Give feedback.
-
Another interesting UI pattern to steal: git-absorb (itself taken from mercurial). |
Beta Was this translation helpful? Give feedback.
-
Hello! I mentioned on the reddit announcement thread that I had recently written down some notes for a "rust git" project idea. I recently found these notes, and after editing them a bit, I thought I'd give you the highlights.
This isn't very structured, but hopefully it should be useful. Feel free to shoot down anything that doesn't match your vision of gitoxide.
UX goals
Start every command with a unique 2-letters prefix
Every gix command should have a unique prefix. In other words, there should be no two subcommands starting with the same two letters (eg
gix foobar
andgix fofo
). There are two reasons for this: to encourage distinctive command names, and to make commands faster to tab-complete.Git is especially bad with this; you have
git status
andgit stash
, and you haverebase
,restore
,rerere
,reset
,revert
, etc. Git also suffers from the "command names aren't distinctive enough" problem; eg it's not immediately obvious what the difference betweengit restore
andgit reset
is.Cover common operations with well-named commands
If you look at Stack Overflow's most common git questions, a lot of them are "I want to do VERY_COMMON_THING. How do I do it?", and the answer turns out to be "use this ambiguously named command with these specific flags". In particular,
git reset
is a bad offender.Some specific suggestions:
gix unstage
command and/or agix add --unstage
option.gix setfile
command, that covers features fromgit restore
; eg copying files from other commits, discarding changes.gix switch
command, same semantics as git. Nogix checkout
.git reset
intogix branch
or some similarly named command. The idiomatic way to go back to a previous commit should make it clear that you're mutating the branch, not the commits themselves. Something likegix branch --set-commit <commit_hash>
.Ctrl_z command
A common worry for non-expert git users is messing up and putting the repository in an unrecoverable state.
While experienced users know that most operations are non-destructive, that operations like merge and rebase that put the repository in a transition state can trivially be aborted, and that the previous state of the repository can usually be found by reading the reflog, beginner users aren't aware of these things, and end up being very conservative in what they do. If anything goes wrong, they'll usually burn the whole thing down and start over.
Having a general purpose "just undo whatever you just did" command would help users be more confident to try commands and see their effect.
Downsides: such a command would be inherently limited in some cases (for instance, it wouldn't undo file changes from an external editor); and it might be extremely hard to write without being incorrect in corner cases.
Stash handling
Git stashes are a really convenient feature when you want to say "I don't want to care about these changes right now. Just put them in a corner and I'll deal with them later".
Stashes become kind of a pain in the ass in a few cases:
Proposal: by default, stashing should be a non-destructive equivalent of
git checkout -- .
. This means:git stash --include-untracked
).--include-staged
,--no-include-staged
, etc) to customize this behaviour.Moreover, stashes should differentiate between staged changes and unstaged changes, and stash them "separately". Currently, if you have both staged and unstaged changes in your repository, doing
git stash; git stash pop
is equivalent togit restore --staged *
(all files are unstaged). Instead it should be a no-op.Stash merge
Currently, if you stash a change to a file, then stage a conflicting change to the same file, then pop the stash, git will create a merge between the two file versions.
If this wasn't the desired behavior, it's hard for the user to cancel this;
git merge --abort
doesn't work, and the pop operation had other side effects to the working directory. As far as I can tell, there's no trivial way to restore the working directory to the state it was before the pop (for added confusion, the stash entry is copied instead of being popped).I'm not sure what the exact semantics should be; stash merging is non-trivial. But at the very least, trying to pop a stash with conflicting changes should fail with a warning; the current behaviour could be accessed with a flag, like
--merge-if-necessary
.Local stashes
This is a little more niche, but I think there should be two kinds of stashes: local stashes, which are associated to a branch, and global stashes, which work as before.
By default,
gix stash
would only look at local stashes. In my experience, it's rare that stashes from a given branch are relevant to another (except when stashes are explicitly used to transfer changes between branches). The existing behavior could be enabled by doinggix stash --global
.Also, I would recommend making it easier to list and browse stashes (maybe with a TUI), but I haven't dug into the question too deeply.
Local gitignore file
Have a file named
.gitignore-local
that is itself automatically ignored, and whose contents are "added" to the regular gitignore when considering files.This is useful if you want to have some temporary files (eg
MY_NOTES.txt
) that you don't want gix to mess with, but you don't want to have to add them to the central.gitignore
either.Diff model
I also had a whole section about the diff model, but it's still WIP. The main points are:
(keeping in mind that all of the above are heuristics, and may or may not be used depending on the size of the changes, the available compute time, etc)
Beta Was this translation helpful? Give feedback.
All reactions