What makes git so hard to use?
Tags: git, ux
Published: 2022-11-16 21:44:33

Git is a beautiful work of engineering. It's blazingly fast even on
massive repositories, and it efficiently manages vast numbers of
branches.

These qualities have made git the dominant source control system, even
though it's hard for humans to use.

So what's wrong with git?

## Git commands are too many, too low-level and hard to understand.

The git program is a collection of 157 commands:

![All 157 git commands](https://www.highflux.io/img/git-commands.png)

The sheer number of commands is a problem. Even though it's pretty easy
to master the most common 10 commands for day-to-day coding, you often
run into commands you've never seen before. So git makes you feel like
you're always a beginner!

Also, git commands are low-level operations, so they don't map exactly
to things you want to do.

You need multiple commands to execute common actions (like "put my code
on GitHub" and "make my coworker's code available in my editor").

Finally, some of the commands do quite different things depending on
their parameters (e.g., `git reset` and `git checkout`), making them
hard to understand.

Git has been trying to create less confusing commands (like splitting
`git checkout` into `git switch` and `git restore`), but this
creates even more commands to learn!

## Git tracks 4 versions of files, instead of just "my" version and "the team's" version.

When I'm working on a file, I mostly think about "my" version (what I'm
working on in my editor) and "the team's" version (what the file looks
like on GitHub).

Unfortunately, git has two more versions that I need to keep in mind:
the one in the "index" (or "staging area") and the one in the HEAD
commit in my local repository.

Because of the low-level commands and the 4 different versions, there's
no single git command that tells git to just take a file I saved in my
editor and update GitHub. Instead, I have to do the following:

```bash
# disk -> index/staging area
git add README.md
# staging area -> local branch
git commit
# local branch -> remote repository (e.g., GitHub)
git push origin branch
```

(The first two commands can be reduced to one with `git commit -a`,
but beware: that will only add changed files and skip any new files you
created while coding.)

Clearly, the 4-version internal git model complicates most common tasks.

## Git doesn't let us safely experiment

Most of us learn new tools by experimenting with them, but git is not
set up for experimentation. It lacks "undo", "--dryrun", and safeguards
against you deleting your own code.

-   Undo would allow you to try some commands and backtrack if they
    don't lead to the right result.
-   A dry run parameter would show you a summary of what a command does
    without making actual changes. If git had that, you could
    confidently explore commands and preview the effects before applying
    them.
-   Finally, a safeguard against deleting code could prompt you with an
    extra warning before executing commands like `git reset –hard` or
    `git push –force origin`[^1]. If all commands that might cause
    you to permanently lose your data had a safeguard, you could
    experiment more.

Because these three features are missing, you can't casually experiment
with git commands unless you want to risk losing code you spent hours
working on.

In summary,** git forces you to convert commands that make sense to you
into commands that make sense to git, and it punishes you for any
mistake you make**.

## The way forward: new tools will improve the git user experience.

Despite the user experience issues, git will probably not be replaced by
a new source control system. Instead, new tools on top of git can make
it easier to use by converting commands that make sense to humans into
commands that make sense to git. They will offer us fewer, more
meaningful commands, automatically manage the 4-version model of git and
make experimentation easy and safe.

Several tools are already out there:

-   [Gitless](https://gitless.com/) [^2]
-   [Sturdy](https://getsturdy.com/)
-   [legit](https://github.com/frostming/legit)
-   [jj](https://github.com/martinvonz/jj)
-   [Sapling](https://sapling-scm.com/): just opensourced yesterday by Meta
-   [HighFlux](https://www.highflux.io/docs/install): our product, currently in beta

We're focused on improving the git user experience. We'd love to hear
your thoughts:  
[discuss with us on Discord](https://www.highflux.io/discord) or [follow us on Twitter](https://twitter.com/intent/user?screen_name=highflux_io).

---
[Mathijs](https://www.linkedin.com/in/mvogelzang/) is one of the co-founders of HighFlux.io

[HighFlux](https://www.highflux.io/docs/install) is a CLI and GUI that incorporates these ideas and is currently in beta.  
[Download now](https://www.highflux.io/docs/install)



[^1]: With an additional parameter to skip the safeguard for automated workflows.

[^2]: We highly recommend reading the research article by the gitless author: "What's wrong with Git? A conceptual design analysis": https://spderosso.github.io/onward13.pdf