Hacker News new | past | comments | ask | show | jobs | submit login
Gitless: a version control system (gitless.com)
516 points by antfarm on Oct 2, 2016 | hide | past | favorite | 372 comments



Git is, like many professional tools, something you simply got to learn.

But like with many professinal tools, you don't need to know everything to get to work.

I don't know all Photoshop or Ableton Live features, but I can improve my photos or create songs non the less.

With these commands you can already start your own repo and work on it locally:

    git init // crate new repo

    git status // show which files are changed and which of them are staged

    git add -p // add "chunks" of changed files to the stage

    git commit -m "<commit_msg>" // commit everything added to the stage with a commit message

    git log // show a list of commits

    git checkout <file> // throw away all changes since the last commit (one file)

    git reset --hard // throw away all changes since the last commit (all files)
If you want to work with a repo from somewhere else like Github etc., you need a few extra commands:

    git clone <repo_url> <target_dir> // clone a remote repository locally

    git pull // download and merge new commits in the remote repo that happened since the last clone/pull

    git push // uploading your own changes after a commit to the remote repo
I think these 10 commands are all that is needed to get your own project into Git.

Yes, the more people are working on a project, the more commands you need, like creating a new branch and getting commits from one branch to another, or amending commits because you forgot something etc.

For a professional tool this isn't too much, I think. The 10 commands I mentioned will be remembered in less than a week. Most of the rest isn't needed often (maybe merge/rebase and branch depending on how you intend to use Git), but they shouldn't take too long either.


    git checkout <file> // throw away all changes since the last commit (one file)

    git reset --hard    // throw away all changes since the last commit (all files)
This is a perfect illustration of why git needs a better UI. Two different commands to do exactly the same thing, with the only difference being that one is for one file and the other is for many files? If you tried to design a hard-to-use UI you could hardly do better than that.

[NOTE: these two commands actually don't do quite the same thing, which is part of the problem.]


They do different things, anyway. `git checkout <file>` will restore files from the _index_, which means it actually discards changes since the last `git add`. It can also be used on the entire tree as `git checkout .`. (As an aside, I think that the different branch vs. tree behaviors for `git checkout` are the biggest UX wart in git.)

`git reset --hard` discards the index _and_ any unindexed changes. You can think of it as essentially `git reset` (which discards the index) followed by a `git checkout .`

I think a lot of the murkiness of git's usability comes from the fact that many commands have collected convenience flags that replicate the behavior of other commands. The rest comes from the fact that `git checkout` and `git reset` can affect any or all of 1) the contents of the working directory 2) the contents of the index 3) the contents of repository metadata like branch tips and HEAD, and you pretty much just have to learn what does what.


Yes, all this is exactly my point. It is nearly impossible to explain the current git UI in a way that isn't embarrassing at best and wrong at worst. And then it's nearly impossible to remember. The number of things you actually want to do 90% of the time is small, so I think there is value in designing a veneer that makes that 90% easy to explain and remember.


Hg did that - unfortunately GitHub won over BitBucket, thus deciding the fate of Mercurial too.


I find Mercurial so much easier to use than Git. Many of the concepts are similar but the hg interface feels much easier to learn and use.


I use Mercurial as a client for git, using the hg-git extension. It works absolutely fine for my use case (small numbers of developers on github, mostly). There are a few rough edges when you want to do things that git doesn't like, like moving tags, and the bidirectional branch<->bookmark syncing isn't quite as robust as it should be, but it saves me having to touch git at all.


At $dayjob we have a mixed bag of hg and git. I found that while git makes great distinction between local and remote (and working directory), hg is more similar to centralized VCSes. Any other remote action than "sync local with remote" requires Blak Magick Mumbojumbo™. Some "common" (as seen by original authors. Local throwaway branch is not such) tasks are sure easier than git, but stepping out of the beaten path becomes cryptic. Git, on the other hand, is of average difficulty for most of the tasks. Your mileage may vary.


I'm curious, what other remote action do you miss with hg? Push and pull (to different remote repos if needed) are sufficient for me. What am I missing?


But they don't do "exactly the same thing, with the only difference being..." unless you ignore the index, which is one of the extremely powerful abstractions that sets git apart. Sure, git could expose a simplified lowest-common-denominator interface that plasters over its differences, but the same interface would (and gitless does) plaster over its strengths and encourage people not to learn them.

I agree with TFA: this isn't a UI issue, it's an abstraction issue. Several of git's abstractions only make cost/benefit sense in a distributed environment. Unbundling the cost of learning dVCS abstractions would make git a better fit for the Cathedral and a worse fit for the Bazaar. This might be what you want, but you should at least be able to understand why other people do not want it.


`git checkout` is indeed a stupid command, because it has 3 modes:

> git checkout [--detach|-b] <commit-ish>

Set HEAD to a new place and sync the working-directory/index to it.

> git checkout <paths>

Copy paths from the index to the working directory.

> git checkout <tree-ish> <paths>

Copy paths from a given commit to the working directory.

This means that "git checkout HEAD file" is different from "git checkout file".

Similarly, `git reset` has 2 modes:

> git reset <tree-ish> <paths>

Copy paths from a given commits to the index, leaving the cwd unchanged.

> git reset [--soft | --mixed | --hard] <commit>

Set *HEAD to a new place, and optionally sync the working directory/index to it.

This is obviously terrible, but changing the names now might be worse.


They don't do the same thing implementation wise, but they do the same thing ux wise. This difference causes all discussions like the above: it seems as if some people like ux "plaster", while others like bare-metal tools.


They do the same thing ux wise if and only if your mental model has no notion of a staging area.


I just stage parts of my changed code before commit. So things I work on are un-staged mkst of the time. Which eliminates the problem, I guess.


They only do the same thing if you haven't previously used `git add`. If you have, `git checkout` will use the contents of the index, not the contents of the last commit.


Then use `git checkout -f` if it so pleases you. There's more than one way to skin a cat.


To be honest, this comment is more evidence of a problem than anything else.


They are not doing the same thing. It's two completely different operations.


You'll have to take that up with /u/k__.


How so? You're the one proposing they do the same thing when they fundamentally do not. To posit so is less of git's "ux problem" and more of just needing to grok git.

I share your concerns for consistent tooling, but the idea of becoming proficient in something without putting in the effort is not reality.


> How so?

Because he's the one who said that they do the same thing.


I don't follow--where does he say that?



This is very close to the result of the study that was I believe he reason to write gitless:

- Most people use git by learning a set of a few commands

- A minority actually understands git on a deeper level

But both groups form a mental model of how git works, and that model is apparently usually wrong, which results in those cases were you get stuck and just start with a fresh checkout and manually reapplying the changes you wanted to commit.


If both groups get the mental model wrong, how can we ever hope to get it right? read the Git source code?


No, but there's a book called "Pro Git" by Scott Chacon and Ben Straub that popped up on HN not too long ago. It does explain git on the lower level without going into the git source code.

This book is over 500 pages, but chapters 1 to 3 will get you up and efficient within 2 hours. Especially chapter 3 (I skipped to it, I kinda knew the basic git commands from "experience"), which goes over branching and how it works. It explains how snapshots are handled and what points to what, which make working with multiple branches locally and remotely a pleasure actually.

It's honestly not to hard to get decent at git. Although I never realized how much of a tool git was until I heard about people writing 500 page long books about it.


I never realized how much of a tool git users were before I knew there are 500 page books about it....

This whole thread is evidence of two opposing viewpoints: "git is too hard" and "git is powerful, professional tool and that requires some effort".

I believe those making the latter point misunderstand the first group (to which I belong): I'm not opposed to putting in some time to learn a tool that's central to my craft.

But git seems to often be complicated not because of the complexity of the underlying problems, but because of choices made in its implementation.

Consider: If you have a decent understand of information theory, you'll be able to use any database system within a short time, even if you never had heard of SQL before. Indeed, with a few years of SQL, you'll quickly understand NoSQL systems as well – coming from Postgres, I was productive in Redis within half an hour.

But no amount of experience with VCSs will allow you dive into git without hitting a brick wall.


Git is a powerful, professional tool that requires some effort, primarily because the UI was accumulated, not designed.


It also was designed for a use case that almost no one actually does which is distributed version control.

Most people use it like a svn with better branching and merging.


Everybody who's ever forked a project on GitHub is using it as distributed version control, and that's a lot of people, so I don't know why you say almost no one actually does distributed version control.


I'm quite certain most of these are sure they are using github and see no difference between it and Git; and "version control" term gives them headaches in same way as "currying" or "first-class function".


Merge Conflicts.

I think a lot of tutorials spend a lot of time teaching you the index/staging (a non-trivial concept that beginners don't need) but don't teach you how to survive merge conflicts and other common tricky situations which beginners are likely to run into if they're collaborating.

Your list is all you need...until you try to `git pull` and it says

> Cannot pull with rebase: You have unstaged changes.

You're only option with your list is commit your changes, but I think it's better to `git stash` then `git pull` then `git stash pop`

Though when you `git pull` you can get a merge conflict and there's two different ways to resolve it depending on if you used the `--rebase` flag or not.

Once you're done resolving those conflicts, you run `git stash pop` and could possibly get yet-another merge conflict that needs to get resolved.

Basically, I'd add `git stash` to your collaborative list. You can't `git pull` without it.


> Basically, I'd add `git stash` to your collaborative list. You can't `git pull` without it.

Of course you can! Git stash is not necessary for any workflow, it's pure convenience.

Best practice is not to pull with unstaged changes. If you want to, then:

  $ git commit -am "WIP"
  $ git pull --rebase
Easier than stashing! But this does mean you're going to need to rebase -i later before you push.

Stash is dangerous for beginners, I don't recommend learning it first. From the stash man page:

"If you mistakenly drop or clear stashes, they cannot be recovered through the normal safety mechanisms." https://git-scm.com/docs/git-stash


Sure, but my guess is it's just as easy to shoot yourself in the foot with rebase -i. Beginners are still going to have a hard time recovering mistakes with rebase -i, even if it's theoretically possible to recover.

Plus, now you need to use `git diff origin` rather than `git diff` to see your changes.


> Sure, but my guess is it's just as easy to shoot yourself in the foot with rebase -i.

No. rebase -i goes in the reflog. stashes don't. The rebase man page does not have the same safety warning that the stash man page does. I have personally witnessed a lot of stash accidents, and not many rebase accidents.

With a rebase, if you have a bad merge conflict, you can abort. With a stash you can't. If you've committed your changes and have problems either forgetting what you're doing, or with merge conflicts, or with being in the wrong branch. All of these cases have more undo options with commits. In the worst case, you still have the safety net of the reflog with commit. With stashes, your only safety net is hunting for dangling blobs using fsck.

Previous threads: https://news.ycombinator.com/item?id=12613062 https://news.ycombinator.com/item?id=12622414


I mean it's just as easy to make a mistake in the first place with rebase -i. Even though one is theoretically possible to recover with rebase -i, it's going to be very hard to recover for a beginner. (You need to know the reflog command, etc.)


I don't think those commands are remotely sufficient to work with git. You're forgetting about merging, traversing history, branch creation, remotes, grokking the staging area, etc. I'm sure I'm missing a lot as well, because those of us who have worked with git for a long time take these things for granted. And it does frustrate me that it's so complex, because Mercurial shows us it doesn't have to be this way. Unfortunately, Mercurial never took off (presumably because it never had a good GitHub analog).


The commands are enough to get through the first month of using git for your own project.

They are certainly not enough to work with Git for your whole career :)


The examples I mentioned were taken from notes I made myself when I was learning git (whenever I had an "aha" moment, I would make a note so I wouldn't forget how to work around it later, since I didn't know the git jargon and thus couldn't Google effectively). Maybe my experience is atypical, but at the time I didn't think I was doing anything novel.


Then they introduce more mess than it's worth. Sooner or later you will have to go back to the original ones and learn anyway.


How are they forgetting merging, remotes, etc? The commands are literally on the front page. The only thing it doesn't have is a staging area, which is a conscious decision that I happen to agree with.


I think you missed that weberc2 replied to a comment listing 10 git commands "that are all you need to get started", not to the top level article.


Ah, thanks. The mobile app view wasn't clear on that.


I'm quite comfortable with git now but I also remember what a pain it was to learn. This included making mistakes and diving deep into git's internals to recover. The question is whether we should make things easier for new versus experienced developers?

If switching to gitless became a thing I'd have to learn something new, but if it made things significantly easier for beginners, maybe my personal inconvenience isn't that important.


Version control is arguably confusing for beginners, but building a shim instead of learning the tool isn't the answer in my head.

I always struggle with "lowering the barrier of entry" and it's not a "I did it they need too do it" it's more of a "Usually high barriers mean it's complex, and learning how to understand complex things is important."

If this was some new novel way to version that wasn't just pretty git, I'd be a lil more excited.


In my previous job, I taught darcs to a designer/graphics artist. It took about half an hour to go through the CLI, and after that he used it successfully and asked me maybe a pair of questions ever.

Now the guy was pretty technical (part of his job was AS development), but he was not a developer.

Darcs's and Git's fundamentals are not that different[0], but Darcs's CLI actually makes sense in and of itself independent from the implementation details, and when it diverges from the older standard (e.g. SVN) it's so that commands make more sense, not less. Meanwhile Git has taken pretty much the opposite tack.

Git's porcelain is a giant steaming roasted turd sandwich, no other DVCS has such a complex, hostile and nonsensical CLI that people tell you you're supposed to learn it from the storage model up and then it'll make sense.

Don't try to shift the buck to VCS/DVCS concepts, while they are complex Git's CLI goes a great way towards making them nonsensical to beginners and non-beginners alike. I routinely used three different DVCS before I had to take the plunge into Git, and it was still a fucking pain in the ass. And that's a problem at every level of resolutions, just compare the hot mess that is gitrevisions(7) to mercurial's (more powerful, more flexible, more readable and more regular) revsets. It's not like revsets are a genius's flash of inspiration either, "hey I'm trying to manipulate sets of revisions, how about I manipulate them as sets?" We're not talking turing award worthy discovery here.

[0] well they kinda are, but by and large the fundamental differences are irrelevant to basic day-to-day use.


That's why we picked fossil over git. The interface is really sane and you can also do stuff from the browser. It gets out of your way. You do not need Python, it can be statically linked easily. It also works on Windows. The usability experience is akin to Mercurial, but even easier to use. Unfortunately it doesn't quie work for bigger projoects (think the Linux kernel or the FreeBSD ports tree) and it can also get slower once you have a lot of history. The repo is esentially a SQLite db.


> Version control is arguably confusing for beginners

NO IT IS NOT. <smack to back of head> That kind of thinking is broken.

Most people who have been around computers on Windows long enough eventually adopt it. They start creating zip files of directories and they put date codes on them. You laugh, but it works.

As such, it's really easy for me to explain Mercurial to them. I simply explain it that Mercurial holds those zip files with some extra information and a pretty GUI. It takes me 30 minutes, max, and they get it.

They have one branch. They occasionally share things with other people. And, very occasionally, they have to merge something--which generally gets resolved by taking this file or that file--but rarely actually merging content.

Things only start to go bad when you start adding concepts that require the user to keep state of the repository in their head. If the end user has to think about the DAG, yeah, THAT'S complicated. And that's broken.

I've now been using git and hg for so long that I know both. I now know enough about git that I have been able to unwedge my teams without just copying the repo (cue xkcd link: https://xkcd.com/1597/). I don't need to spend hours of Googling anymore, I just need quick reminders of "Oh, yeah, that stupid flag."

And, you know what, I have never, ever been in a situation where I thought "Gee, I really wish I was in git rather than Mercurial." The converse, however, happens at least once a week.

Perhaps one day my teams or my repos will be complicated enough that the light dawns. The fact that the *BSD guys still operate using CVS and Subversion makes me skeptical.


For me the problems are always merge conflicts. Don't know why, in SVN I wasn't afraid of merge conflicts, I just opened a GUI, clicked on some arrows, picked the parts I want and parts I don't want, save and done. In Git, even with gui tools, I often end up with a mess of .BASE, .LOCAL, .REMOTE files, then I can't merge it all properly, and even if I do it asks me to commit the changes again and it's a mess, so I just clone the repo again and copy the files (xkcd #1597).


If you think merging in svn is easier than git then you haven't seen the pathological cases of svn merges. The problem is svn has no concept of a repo root or branches, it only has directories, so sooner or later things get very very broken.


I don't understand this rationale. Are you saying that Git's UI is perfect, and there's no improving it? It's not, and gitless does, indeed, improve on it.

We should be celebrating better UIs over important tools, not saying "I made great effort to learn it, therefore learning it with less effort is inferior". No. If it does everything Git does, but more easily, it is strictly superior.


Well-said. We also know that git was originally hacked together in two weeks after Torvalds had to ditch the better-designed product they were using, Bitkeeper. It's almost as if a bunch of Linux developers kept hacking stuff into it with no concern for UX and telling people they were idiots if they didn't like mastering unnecessary complexity.

Meanwhile, unlike Git, I understood most of Gitless's commands before the tutorial started explaining them. Opposite experience I got with Git tutorials where I kept questioning why it would be done a certain, unintuitive way. This is definitely an improvement.


Git's UI will never beat Git's command line. Not even close. It may be easy, but the command line is far more powerful, and way faster. Basic git usage is around 10 simple commands or less, and it's not like it's not well documented.


git UI == git command line in this context. I don't think anyone in this subthread is talking about GUIs.


My apologies - I saw UI and immediately thought of Git's GUI clients.

I don't think git's command line needs to be changed, though.


Because it's perfect? Because it's familiar? I'd be curious to know why.


Command lines have no discoverability though.


Not true - you have Tab, --help and man pages.


What I'm saying is, Gitless is cool, BUT beginners are always looking for ways to cheat the effort. My point is, this is a great tool if you understand git, and want to use a shim, but for beginners, going straight to the shim is not good.

>If it does everything Git does, but more easily, it is strictly superior.

In the abstract I agree, but if an junior dev goes "oh, I just use gitless because it's easier" and DOESN'T understand git, it's a problem. That's my point.


cheat the effort

I'm always suspicious of arguments like this, because they have a Luddite quality to them. Isn't sending email versus handwritten postal mail "cheating the effort" of communication?

git is a lot of effort to learn because its command line is inconsistent and it is frequently unclear what it has done, why and how to recover from it. It is worth asking if this is really necessary.

If a system has a high percentage of beginners pressing the wrong button and losing time and effort as a result, maybe someone should move the buttons?


This is spot on, thank you. The git porcelain is very inconsistent between commands, and that really muddies the view of the underlying model. I would argue that a cleaner porcelain would lead to more easily building a mental model of the data structures.


I think there's a difference between learning something that's necessarily complex and learning something with an overly complex design. According to their analysis, the design changes they've made do away with unnecessary complexity.


It's like with IDEs.

Eclipse has stuff like workspaces with multiple projects and others have simply projects. What to do with these workspaces?

Same goes with Git. Simple VCS have central repositories and a working copy. Git has multiple repositories and every one of them can have a working copy. Other VCS don't have a stage, you simply commit your changes directly into your repository.

It's not only that these tools have different commands and stuff like Mercurial or Subversion has easier commands etc. but they really have different concepts that need to be considered while working with these tools on a daily basis.

But you don't have to internalize them on your first week or month working with them. When you got your project in the System it's mostly save and if you don't have complex workflows you can still reap the benefits of VCS with Git without knowing everything.


I may have misunderstood you, but you do realize that Mercurial is also a DVCS like git, right?


The problem is better solved with good tutorials. Cutting corners is a bad idea here so encouraging newbies to do that is more hurting than helping them.


> Git is, like many professional tools, something you simply got to learn.

Or, you can use a tool that is built for purpose aka doesn't suck). I don't use a Stanley #55 Plane to trim an edge even though it can.

Mercurial, the author notes, doesn't have most of the pitfalls. Yes, everybody persists in using git because "Linus used it".


I persist in using git mostly because it doesn't also mean I need to have python installed everywhere.

I recognize this may be a minority reason, but that is a significant one. The rest amount to being able to rebase/reorder my commits.

At no point does "linus used it" factor in. What genuine technical points about git besides "doesn't suck" are you espousing as reasons I should switch?

Note, my workplace:

a: uses git

b: is about as likely to switch to hg as a pig would be to fly

c: follows linux upstream closely (we do kernel stuff)

I know of the following things that would be reasons to move to hg, however they're more in the "nice to have" rather than "need" category.

a: evolve extension

b: more consistent ui

If I were to list out all the cons for hg from my current perspective, here would be my top 5:

a: have to unlearn fetch/pull as they are not the same between tools, which is right is academic at this point

b: have to unlearn a lot of git use over the past 8 years, not against it but I need a good carrot to bother

c: now I have to install python on some low power systems, honestly this is dumb needing to install a scripting language just to use a VCS, and I use python daily, but its extra bloat that really shouldn't be needed.

d: last I looked (~6 months ago), i'd need to install extensions to recreate most of my workflow, again, this boils down to more effort than sticking with the status quo which by and large works out of the box.

e: would be nice if hg proponents would stop with the "git users are brain damaged by bad ui" posts, it honestly just makes me roll my eyes and move on, not rethink my position, SHOW ME WHY IT IS BETTER, stop berating as that isn't helping and at best is making me think people are treating VCS choice as a religion or political affiliation, which is easily dismissed and not at all worth my time to reply.


> I persist in using git mostly because it doesn't also mean I need to have python installed everywhere.

That is a perfectly valid objective reason. It surprises me, given that I do embedded development and have yet to be in a position where Python in my toolchain is an issue, but I'm happy to concede it.

> c: follows linux upstream closely (we do kernel stuff)

Then git is your horse, full stop. Even as a Mercurial person, if I was following kernel stuff I'd use git, that's just common sense.

> e: would be nice if hg proponents would stop with the "git users are brain damaged by bad ui" posts, it honestly just makes me roll my eyes and move on, not rethink my position, SHOW ME WHY IT IS BETTER

You do realize that the UI is more than the majority of the tool, right?

People have done what you ask for. Repeatedly. Including the parent post. Git power users have written extensively of the various UI brain damage and the problems it causes for non-power users.

Git people concede the UI sucks and still persist in starting new projects with git. How should that be classified?

> If I were to list out all the cons

Do be cognizant that with the exception of objecting to python, most of your list of cons is: "I've used git and optimized for it so changing is difficult". If Microsoft/Oracle were attempting via network effects to foist such a broken tool on the open source community instead of Linus/github, people would be screaming.

Personally, I can use either now. Also, personally, I now consider Mercurial to be a not-so-secret productivity advantage (well integrated with Windows, no wedged repositories, no wasted time recovering, can explain how to use it to neophytes so executive level people and non-programmers can use it, etc.). I know that my Mercurial teams won't waste 5% of their time fighting their source code system every single week--they won't even think about their source code system.

My beef is that beginners think "Oh, everybody uses git so git is fine so let's use git". And then, once they've made that mistake, now they feel they have to defend it. And that's not cool.


> It surprises me, given that I do embedded development and have yet to be in a position where Python in my toolchain is an issue, but I'm happy to concede it.

Admittedly its weak but I've used it to run things like git on some really small systems. I'd rather not have to try to get python running on something like an AVR. But to each their own. Not sure what embedded development is meaning here exactly but no matter.

> You do realize that the UI is more than the majority of the tool, right? > People have done what you ask for. Repeatedly. Including the parent post. Git power users have written extensively of the various UI brain damage and the problems it causes for non-power users.

I'm looking more for what advantage hg itself gives me, less about how much git sucks which is at this point beating a dead horse.

> Do be cognizant that with the exception of objecting to python, most of your list of cons is: "I've used git and optimized for it so changing is difficult". If Microsoft/Oracle were attempting via network effects to foist such a broken tool on the open source community instead of Linus/github, people would be screaming.

Indeed, but that just points to after 8-9 years of using git, minor gains in using hg just don't seem as warranted. To date most of what I have seen with hg hasn't shown me what I will gain from switching will be greater than moving. Perhaps thats due to not having to use hg constantly but with things like magit I really don't notice the git ui a lot unless I choose to drop into the command line.

> Also, personally, I now consider Mercurial to be a not-so-secret productivity advantage (well integrated with Windows, no wedged repositories, no wasted time recovering, can explain how to use it to neophytes so executive level people and non-programmers can use it, etc.). I know that my Mercurial teams won't waste 5% of their time fighting their source code system every single week--they won't even think about their source code system.

For my work I've no real need to integrate with windows, not sure what wedged repositories is referring to. Recovering is vague but as a worst case the reflog has always been an emergency fixer. I've not really experienced this to be honest and I'm basically the go to guy for git with my team.

> My beef is that beginners think "Oh, everybody uses git so git is fine so let's use git". And then, once they've made that mistake, now they feel they have to defend it. And that's not cool.

Thats fine, but a bit different than the original statement of Linus uses it therefore we must. It is more git is widely used, ignoring it or not knowing how to at least basically use it isn't a tenable position imo. But to each their own.


git wasn't designed to be used by humans. I can't find the quote, but Torvalds said at one point that intention of Git was to provide a content-addressable graph that more human-friendly tools could build upon for different use cases.

Those 10 commands are the beginning of the iceberg when you actually start using git with teams. Where are `rebase`, `merge`, `branch`, etc? These are all commands I use daily, they are complicated, and it's trivial to shoot yourself in the foot.

The problem is that you can learn those 10 commands and things will work, until they don't, and you as a beginner are now spending hours trawling StackOverflow to figure out how to, say, pull a commit from one branch to another (you might not know that such a process is called "cherry-picking").

It's telling that Torvalds said this more recently about git:

> The first Git For Dummies and Git Visual Quickstart books are going to be out in a couple of months, and that is the beginning of the end as far as I’m concerned. Those books mean the end of git expertise and github reputation as reliable indicators of geek status. Once a technology is adopted by the masses the extreme geeks find something more esoteric. Look at what happened to Ruby on Rails. The people stumbling their way through Rails to-do list tutorials have never even heard of DHH.


I could be wrong, but I think the article that the Torvalds quote came from was purely satirical [1]. If you look at the tags it says it was posted under satire. Got me at first too!

[1]: http://typicalprogrammer.com/linus-torvalds-goes-off-on-linu...


Git wasn't originally designed to be used by humans. There was a separate "porcelain" built on top of git, but I no longer remember what it was called. But enough people wanted to just use git proper without the porcelain that the git core commands evolved into a porcelain themselves, and the separate porcelain layer was deprecated.


Here's one quote from Torvalds to that effect:

http://www.gelato.unsw.edu.au/archives/git/0504/0873.html


After having used git for a few years, I identified what commands I use most frequently and have created two-letter aliases for these;

    alias st='git status'        # STatus
    alias dp='git diff'          # Diff Pending
    alias aa='git add .'         # Add All
    alias di='git diff --cached' # DIff
    alias cm='git commit -m'     # CoMmit
    alias pu='git push'          # PUsh
I've added comments above to show you what I think in my head when I type the two-letter alias in question.

I have a few other two-letter aliases for git as well but the ones above cover about 80% of my use I think.

For the remaining 20% I usually type the command out fully even if I have an alias for it, because those less-frequently used commands are harder to remember the aliases for, whereas the aliases that cover the 80%, I have those in my fingers now without having to think about it.


It's way superior to use git aliases instead of shell aliases. In this way autocompletion and autocorrection will work.


For the specific aliases I have, the only one that needs an argument is commit and you can't auto-complete a commit message anyway ;) For the aliases that I sometimes specify a file path for, bash is still able to tab-complete that. So for me, shell aliases are actually the best.


I think git's concepts are simple and worth learning (unlike what the gitless people said).

That being said, the command line interface is "meh" at best and full of byzantine options.


> I think git's concepts are simple and worth learning

For what purpose? The reason for using a VCS is to get your job done. If gitless does that, why should I need to learn the concepts of a content-addressable graph storage and traversal format?


For instance, git has a notion of staging area (the index) where you collect the changes that go into a commit. In gitless, all changes to tracked files are committed. The index goes a long way towards making nice commits that can be understood by other team members, pass tests, etc.

Similarly, the stash that allows you to save your uncommitted changes before switching branches is also quite worthwhile.


For all intents and purposes, gitless has an index too. It lets you specify upto hunk-level granularity what you want to include in (and exclude from) each commit.


Actually I miss using Mercurial and most customers that I work with, refuse to move beyond Subversion into Git.

Those that do move, just use Git workflows as if it was Subversion.


Example usage from the article:

    $ gl checkout foo.py
    You have uncommitted changes in foo.py that would be
    overwritten by checkout. Do you wish to continue? (y/N)
    > y
A cheat sheet with those 10 commands are enough to get started, but Git takes a bit to grok properly ( https://xkcd.com/1597/ ). More importantly, it doesn't have to be user hostile. Professional tools in manufacturing are very expensive and last decades. Software lifecycles are shorter and easier and far cheaper to replace.


True. But the argument breaks down (for me) when you consider all the computing power we have, what we're building (i.e., lack of dog fooding), etc. and this must learn tool is the best we got.

NO ONE would use Photoshop or Ableton if they're were as messy as Git. Nuff said.


The problem is the world isn't just git. There are thousands of other things to master at any given moment. Putting a veneer over something you aren't interested in mastering and using that seems like a valid strategy.


I just use Git GUI. Click click and I'm done. For more complex tasks I open up Git Bash eg. git merge --no-ff <branch> which is the equivalent of "gl merge" command in gitless


Yep, that's pretty much my git repertoire! I would add branch and merge to this list - conceptually simple, but they add another dimension to version control.


> Git is, like many professional tools, something you simply got to learn.

Nailed it.


Agreed. I'm seeing terms like "elitist" being thrown around below for "git apologists" when it's simply a matter of learning a tool. Not everyone needs all the power of the git CLI and the complications it brings - but when you do need it, it's there to fix the dumb things we all do sometimes.

I think if you look deep in the guts of Clearcase for example you will see nastiness that makes git look like the ls command.


" I'm seeing terms like "elitist" being thrown around below for "git apologists" when it's simply a matter of learning a tool."

Some tools people encounter seem unintuitive and have a steep learning curve. Others that do the same thing are super easy to understand and learn. Git vs Gitless is a good example where Gitless instantly clicked with hardly a thought. That means it was a superior interface. That also means anyone telling people they need to suck it up and just accept bad interfaces that smart people were able to learn with enough wasted energy is a bad idea.

Reminds me of those guys when I first started dealing with Linux who told me I was just being slow or lazy for expecting an installer that just required a little bit of input like I had with Windows. Anyone should know everything about handling partitions, configuration of low-level graphics, init systems, whatever. These days, the installers are point-and-click for average case while including options for others. So, why did the Linux people tell me that early on? They were elitist snobs peddling bad UI's and seeing no value in good ones. That simple.


No-one is disputing the power of git. People are merely pointing out that it's textual user interface is clunky and inconsistent. Just because it won the DVCS wars doesn't mean the conversation needs to end and we have to accept this is as good as it gets. It won despite it's CLI not because of it.


> Git is, like many professional tools, something you simply got to learn.

No. Why do people think "professional" has to mean "poorly designed"?

But then, the rest of your post seems to miss the point of this thing entirely. You go on to say that you basically only need 10 commands...which is pretty much the insight that lead to Gitless in the first place.


"Professional" doesn't mean "Poorly designed". It means "designed so that people with lots of domain knowledge and experience with the tool find that it never gets in their way."

In that sense, git is a professional tool. If you know everything about it, it doesn't get in your way. The problem is when you don't know everything about it..


In this sense, trivially, every tool is a "professional" tool, since if you just rote-memorize every aspect of it you know how to do everything it can do.

The problem with git is the lack of coherence in its default UI. Multiple ways to accomplish the same task, git commands which perform incredibly different functions depending on (invisible) context, inability to decide whether commands or flags should act as the highest-level switches...

It is simply the case that, no matter how beautifully and cleanly designed git's internals might be, the interface it presents to them has zero conceptual integrity.


No, trivially, there can be tools that you know inside out which still present roadblocks to perfectly ordinary tasks and be a bad fit for the domain they operate in.

Visual SourceSafe springs to mind here...

Git, by comparison, is very flexible and allows you to do an awful lot, when you've learned it. You can learn SourceSafe inside out and still have it be a total pain in the arse.


Again: git as some sort of Platonic ideal of an implementation of a DAG I don't care to argue about. But git's default user interface I will argue about until I'm out of breath, then keep arguing about.

Nothing in that interface is designed to aid in learning. Nothing in it is designed so that mastering one task provides discoverability or intuitability of how to perform another task. It is a complex mess of inconsistencies, discontinuities and obscurities which point more to a lack of design or even of someone with authority to perform design than to anything else. It can only be "mastered" through rote memorization, and bears no necessary or useful relationship to the underlying data models and structures whatsoever.


Eh. Fair enough, my pedant mode just kicked in when you said any tool could be a 'professional' tool in the sense the parent poster said.

I have no particular view on how good or bad git's command line is - I have greatly enjoyed using SourceTree though, and the underlying DVCS seemed not to get in the way.


I think this is because the commands are poorly named and badly organised. Professionals will use it frequently enough that they remember everything they need and find it easy from that point forward, but for beginners the unintuitive commands are a double-whammy. It's hard to find the command you want, and the poor naming is a hinderence to building a good mental model of the system.


The burden of having to know everything about it, is precisely what gets in your way. Granted, I use an actual tool (sourcetree) that abstracts away the BS that is the git commandline.

This idea that 'if you don't like the tool, it's because you're not good enough to use it, because you don't know everything about it' is elitist hokum.


Is an aircraft cockpit a poorly designed ux? It does require a fair bit of learning.


yes. and that's why as new planes are being produced, both commercial and small planes, they are replacing the older cockpits with fully electronic modern cockpit controls (with non-electronic secondary controls for power failure use)

many NTSB studies show that even master pilots with thousands of hours of training and flight time make (often fatal) mistakes due to confusion in understanding the cockpit readings


Fully electronic "modern" solves nothing without training. Part of the reason Air France 447 crashed was because the crew did not react correctly to the instruments, even though it was an Airbus with all its gee-whiz electronic stuff. Boeing has been more conservative.


There's a standard tech-nerd bias that assumes that technology will always save us, but just throwing electronics at the problem doesn't necessarily solve anything.

For example, the Army found that using glass cockpits doubled or quadrupled the accident rates in UH-60 and OH-58 aircraft respectively, increased it by ~30% in the AH-64, and reduced it by ~40% in the CH-47.

http://oai.dtic.mil/oai/oai?verb=getRecord&metadataPrefix=ht...

http://www.usaarl.army.mil/TechReports/2001-12.PDF

A five-year NTSB study found that although glass cockpits had twice the incidence rate of fatal accidents. The study concluded that glass cockpits do not show a safety benefit. This remains the position of the NTSB.

http://www.ntsb.gov/safety/safety-studies/Documents/SS1001.p...

http://www.ntsb.gov/news/events/Documents/2010_Glass_Cockpit...

http://www.ntsb.gov/safety/safety-recs/recletters/A-10-036-0...

The reality is that simpler is sometimes better. Mechanical instruments each do one thing and they do it well. Vacuum-driven systems are simple and extremely reliable. You cannot fly a 100% glass cockpit, period.

What glass cockpits really do well is information integration. That makes it easier to surface relevant information for the pilot but it also means that pilots have to handle more complex systems that are throwing more information at them, and yet also may not be throwing the right information at them.

This is an inherently one-way street, the reason we have the instruments we do is because they're relevant, you can't go hiding relevant information from the pilot. As such, NASA recgonizes that glass cockpits and cockpit automation impose a higher cognitive load on pilots. It's very simple and straightforward to interact with a traditional cockpit, but with a more advanced cockpit you also need to have a correct mental model of what's happening in the background, otherwise "cognitive mismatch" will result.

Just like any other abstraction - it's nice when they work but all abstractions are "leaky" to some degree or other and you need to know how it works and be able to route around the problem to fix the cases where it fails.

The long and short here is that experience and frequent training are the key factors in aviation safety and glass cockpits actually increase the requirements in this area. They're nice when they work but they certainly are no panacea.

http://human-factors.arc.nasa.gov/flightcognition/research/s...

https://www.thinkmind.org/download.php?articleid=achi_2012_1...


Professional means it doesn't sacrifice functionality in favour of making things easy for newbies. This is a philosophy I approve of for all software. Vim is great because it offers power at the expense of having a little bit of a learning curve. A shell gives you unlimited power compare to a stripped down and locked down GUI.

GUIs and "UX" are generally antithetical to making a computer do what it does best (automate things instead of creating more busywork).


> GUIs and "UX" are generally antithetical to making a computer do what it does best

I agree with you, but although CLIs are explicitly automatable, they are almost never are because most operations are one time deals. If you have evet set up a Linux server I think you'll understand what I mean. The CLI is also a usability nightmare with no discoverability.


I use configuration management tools to set up multiple nearly identical Linux servers with nearly identical configurations. It's totally repeatable. Look into Ansible, Chef, Puppet, or SaltStack.


"GUIs and "UX" are generally antithetical to making a computer do what it does best (automate things instead of creating more busywork)."

Except for helping the 6 or so billion people in their daily lives, but hey, the iPhone would be 'better' if it just had 'bash'?

Read your email lately from bash?

Didn't think so!


Bash is what I miss in iOS, I used to jailbreak just for getting a shell.

Now, I use pythonista as a python-shell. Being able to chain a couple of commands and fix a good-enough solution saves a lot of time in many cases such as web scraping on-the-go.

I know this may be an extreme use case, but if iPad is going to be a laptop replacement we need to be able to get a way to speak with it without immidiate access to a laptop.


False equivalence. We wouldn't have billions of users if there were no other agents than users. You can't create an iphone using an iphone.


"False equivalence. We wouldn't have billions of users if there were no other agents than users. You can't create an iphone using an iphone."

It's not a false equivalence at all.

The necessity of lower-level technology in the creation of higher-level technology does not imply that the lower-level technology is somehow 'better' or 'superior'.

You are using a UX right now to read and respond to this.

It's crazy to posit that 'UXs are inferior'. Positively wrong.

In the vast majority of cases, UX's are superior to shells. Maps, news, social media, browsing/buying things, listening to music, making music, photo editing - there are actually very few use-cases wherein the shell is advantageous. Even emacs is a UX of sorts.


Well, first off: I didn't claim that "UXs are inferior", whatever that means. Every interface is a UX. I assume from context you're talking about polished GUI:s.

GUI:s are superior for the specific (limited) use cases they are designed for, inherently since they were designed to excel at those use cases. They are however less optimal when you want to diverge from those use cases and create something new. This is where malleability/modability comes in, and where CLI:s, bash, scripting, programming comes in, and you can't use limited-scope apps for that.

All tools are best at what they were designed for, I agree with you there. I'm however not sure how I in your mind was wrong before. The two are intrinsically bound, but it's undeniable that apps can't exist without tools, but tools sure can exist without apps.


Not with bash but with less :-P


Hell yes. Why does [established practice] have to mean [best practice]?

With all the security concerns and regulation regarding flight, it's easy to imagine how hard it is to move forward and innovate in usability.

I'm not saying upending git for something better would be trivial, but I don't want to constrain my imagination by thinking it's not possible.

If you can coherently explain what you need [git replacement] to do, and explain it simpler than you would explain git itself, then you have an outline of a superior tool.


A rather ironic question, given the history of ergonomics and human factors research in aviation.


Why would someone write a tool for 10 commands?!


No one here did that. What are you talking about?


Git bisect should be on this list.


I'm surprised at how many people are responding negatively to software that improves user experience.

Suppose we had started out with the command UI that gitless has and someone came along and tried to sell us the current git cli UI. It would be completely ridiculed.

The only thing possibly questionable about the gitless interface is that it does away with staging. However, you can always fall back to git for staging functionality if you like, and use gitless for most other commands. I think it is a win.


I think the author address that point in the introduction:

> Experts, who are deeply familiar with the product, have learned its many intricacies, developed complex, customized workflows, and regularly exploit its most elaborate features, are often defensive and resistant to the suggestion that the design has flaws.

Having spent dozens, even hundreds, of hours learning the intricacies of the Git command-line, it must be extremely shocking and insulting when you are told that those efforts were in vain, because the original UI was not very good and an alternative can be grokked by people of varying levels of technical competence with only a fraction of the effort you put into the original thing. I think this is what we're seeing here: people will try and defend their time investment by arguing that a professional would learn the hard thing and not lower himself to easy-to-use tools, that the new UI hides some powerful features that are rarely used, etc.


Indeed. Also known as "sunk cost fallacy".


I think it's a little different from that actually. That's normally about the merits of ongoing financial investment, but I get your analogy and there should be a name for it because you see it all the time from compsci types.

How about "sunk knowledge fallacy" or something like that?


> "sunk cost fallacy"

I like to spot those, did not see this one though, but indeed, sunk cost fallacy it is. Well spotted :)


Using artificially complex, unfriendly tools is a form of honest signaling. [0]

Making tools complex and painful, denying their complexity, and scoffing at the very notion of allowing a non-expert to accomplish what before required esoteric knowledge is the way the tribe of self-styled Real Programmers protects its integrity.

[0] https://en.m.wikipedia.org/wiki/Signalling_theory#Honest_sig...


"dumbed down" only improves the user experience of new users. It hurts power users and is rarely useful to anyone other than newbs.

It can be net gain for infrequently used and rarely mastered tools. Source Control should the 2nd (after editor) most mastered tool of a developer.

Many will assume this is "dumbed down" interface and thus overall bad for source control tool.


> "dumbed down" only improves the user experience of new users. It hurts power users and is rarely useful to anyone other than newbs.

That's only true if the power users perform a completely different group of tasks from the new users, or if the "new user" interface is made wholly incompatible with the "power user" interface.

If the power users still needs to perform the same basic tasks, the simplified and easier interface will likely make those tasks more efficient for the power user as well.


>I'm surprised at how many people are responding negatively to software that improves user experience.

At the cost of doing things technically correct.


Git is powerful. While the underlying architecture has beautifully simple aspects arguing that the complexity of the git tool-chain is simple is similar to arguing that TeX is simple as it is written in a simple language. Git is managing trees of file-sets in a distributed manner. It took many generations of configuration management systems to get there.

Git is bottom up. Understand the inner workings and you know what you can do. But coming from a user perspective there is a gap - first one needs to wrap ones head around the tool. Git imho. is more a framework than a tool. On Stackoverflow simple questions yield different answers all yielding results but having various trade-offs. Usability is also about orthogonality and looking from a user perspective (not an implementation perspective) Git offers often quite a number of paths getting to a certain goal.

Individuals, teams and tooling all trying to settle on certain workflows enabled by git effectively deciding to use only a subset. Particularly when it comes to teams agreeing on workflows becomes important. Git as a tool is here helpful in the sense that it enables almost everything. But for a team it takes more than agreeing on using Git. Other tools come with more comprehensive practices.


As a tangent, I think calling git a distributed system is misleading. Git is primarily a history manager for a local directory tree that has commands to sync with remote machines. Having to type stuff like

  git remote add mothership ssh://foo@bar.baz
  git push mothership
in order to sync is not what I usually associate with a distributed system. The word distributed conjures something that's more like dropbox, where things sync transparently.


"Distributed" means something other than what you think it does. Dropbox is not a distributed system. In fact it is a good example of a centralised system.


"Distributed" is, by popular convention, associated with systems that span multiple computers (or even processes on the same computer).

"Decentralized" is associated with systems without a central point of failure or control.

Git qualifies as both, and Dropbox only qualifies as distributed.


Being distributed is essential for gits design. It explains why there are strange sha1 ids instead of incremental revision numbers like with svn, for example.


Very cool. The idea which I liked most, is the ability to switch between branches, even though you still have uncommitted changes. With git, I'm forced to either make an extraneous commit, just to enable branch switching, or stash all my changes into a stack which I may later forget all about. Both of the solutions above are really cumbersome and prevent easy context switching.

The only feature I noticed missing, is the ability to stash changes. I use this most often to move changes from one branch to another branch, without cluttering history with an extraneous commit. How would this work on gitless?


> With git, I'm forced to either make an extraneous commit...

You only need to commit or stash if there are conflicts, and many time there aren't, so you can first try to switch branches without stashing.

> The only feature I noticed missing, is the ability to stash changes. I use this most often to move changes from one branch to another branch

I started a big ol thread on stash yesterday, but there are a bunch of safer alternatives to stash. You never have to clutter history, you can always move things around and still keep it clean. Problem with stash is it circumvents git's normal systems, so it's a little dangerous (which the stash man page mentions.)

https://news.ycombinator.com/item?id=12612630

If there are conflicts, you could do this instead:

  $ git checkout -b work
  $ git commit -am "WIP"
  $ git checkout another_branch
  $ git cherry-pick work
  $ git branch -D work
Exact same effect as stash with no clutter left over in the history, and much safer. The advantage here is your changes are put multiple places and referenced by git, so if anything ever goes wrong it's in the recent reflog. With stash, if you have problems, your only option is to use fsck.

Given that the whole point of gitless is to avoid super confusing and intimidating commands like fsck, especially for beginners, it makes sense to me they chose not to include stash.


The whole advantage of stash, the way I see it, is that you don't need to type out a whole bunch of commands to stick something into another branch and deal with remembering where you put it and what you called it and so on.

I started out using secondary branches since that was the intuitive way of doing things, and I had issues with stash before, but after a while I went back to using stash again because it's just so much faster to stash my config differences, do all the necessary merges or pulls or switches, and then just stash pop. A large part of the advantage is that stash is a bit orthogonal to the usual workflow, so it goes in a specially defined place in my brain vs being yet another branch, especially if I already have work/dev/backup branches for other purposes.

I agree that I wouldn't recommend using the stash to beginners, though, it does really odd things at times if you are not clean with it. First time I used stash, I lost all my code and nobody could figure out how to get it back. :P

But that the thing - I never stash crucial code, just things like settings that are special to me and not other developers, so they'll probably never be pushed.


Stash for you is fine, you obviously know what you're doing, and you use it carefully. And if you're comfortable with fsck, you really don't have to worry.

OTOH, the alternative workflows are really not that hard, it's really not a ton of commands compared to using stash. The single most common use case I've heard so far is switching branches, and for that you can skip stash the majority of the time, many people don't seem to know that.

Your example was stash during a pull, if you do that, your workflow is:

  $ git stash
  $ git pull
  $ git stash pop
The alternative is:

  $ git commit -am "WIP"
  $ git pull
  $ git reset --soft
Not only is it the same number of commands, and safer, it's also less to remember because you don't have to use the stash subsystem at all. Commit, pull, and reset are commands you have to know regardless, you can't avoid them. Stash isn't one you have to know to use git. Stash is adding to the things you have to remember, or taking up space in your head that could be used to learn flexible ways of making temporary commits & branches.


I don't know if I really know what I'm doing... feel free to correct me if something feels off.

I'm not following your alternative. Did you mean "git pull --rebase"? Because this will result in there being a WIP commit in the middle. I try to pretty much never do pulls like this, I'm in the "rebase everything to smithereens camp".

I don't want accidental merges. I do not want to have to rebase because I got a commit in the middle and it's named funny. And what I also don't want is having to deal with merge conflicts in the rebase or merge in case incoming changes don't like the changes in the WIP commit.

It's a lot cleaner to just not have the stuff in there at all, pull, and put it back on top. (like the stack that stash presents)

Yes, I am that lazy.

This is not really the way I used to do it. An example is just an example, the situations are many. Maybe I want to pull. Maybe I need to rebase my stuff. Maybe I need to switch to another branch to show something to a coworker.

I'd have to make a special branch, commit to it, and then grab the commit hash and cherry-pick that whenever I needed it. Because I would need it in all sorts of different situations. So part of the issue was keeping track of the hash. But the bigger problem was how much work I'd needed to do if I ever needed to bring those changes up to speed again. With stash, I get a merge conflict and I resolve it, and that's my new stash again, I don't even have to do anything. With a commit or cherry-pick, I have to undo it, fix it, commit it, and now manage a new hash.

I find stash easier to manage in my head specifically because it's a separate thing on the side so it doesn't get mixed up with all my other branching. It's very little headspace at this point, and mostly a decision tree in the form of:

- is the staging area empty and I want to start doing work? stash pop;

- is the staging area currently holding my stash changes and I want to do some things with git? stash.


> Did you mean "git pull --rebase"?

Yes.

> Because this will result in there being a WIP commit in the middle

No. Your WIP commit will always land at the end. Anything you pull will rebase to before your WIP commit.

Doing a commit+pull+reset will always work exactly as easily as stashing.

It's no less clean to commit & later reset than it is to stash & later pop. The difference is that if you commit you have a bigger safety net than if you stash.

I totally understand that stash feels easier, a lot of people agree with you. But I don't think it's true once you dig down and learn how to not use stash. And stash is more dangerous when something unexpected happens.


> No. Your WIP commit will always land at the end. Anything you pull will rebase to before your WIP commit.

I was talking about the non-rebase version.

You didn't address the rest of my post: there are other cases. This will work for that particular case, but it's not a general-purpose solution.

If I have branch X with config changes, and coworker wants me to switch to branch Y but I still want my config changes, what do I do?


Stash is not a general purpose solution. You don't ever need to stash. There is nothing you can do with stashes that you can't do with core git commands, and the reverse is not true. Git could eliminate the stash command tomorrow without any loss of functionality.

What if you already committed your config changes to branch X, and your coworker wants them in Y? What if you you're working along and you have commits, staged changes, unstaged changes, and you need to branch 3 commits ago instead? Stash doesn't help with either of those, and the workflow I'm advocating - just use commits and branches for temporary work - does.

Stash really only helps you if you don't like to commit often, and you spend most of your time with unstaged changes in your working tree. Nothing wrong with that, if that's how you like to work, but I think if you spend some time getting used to committing more frequently you may find it much more flexible and much safer and more forgiving than trying to keep everything straight in the working tree alone.

If you have uncommitted changes in X, and you want in Y instead, then you can:

  $ git checkout Y
  $ git commit -am "config changes"
If you get merge conflicts, or if you want to keep the change in X too, you can:

  $ git commit -am "config changes"
  $ git checkout Y
  $ git cherry-pick X
The first case is fewer steps than stash, the second is just as easy as stash.

Popping a stash and cherry-picking a commit have the same process if there's a merge conflict, except that with a commit, you have undo capability if you merge incorrectly, and you have a safety net if you get lost or screw up in the middle of the resolution. With stash, you're stuck with a bad merge, and if you lose your stash -- and it happens -- you have to hunt for it by searching for dangling blobs.

You made a big deal out of having to create and remember and lookup hashes, and I don't see that as being an issue at all, and it's not a problem in my experience. You're comparing this to stash, after all, and stash only works on uncommitted changes, so there is never a case where you'll need a hash, because the stash equivalent is always at the tip of the branch, you can always use the branch name instead of a hash.


I didn't call it a general purpose solution in that context, nor did I call it a general purpose solution for everything. I am saying that I needed a general purpose solution for a situation that occurs often in many variants. For my situation, without stash, that was creating a commit and cherry-picking it places. Stash makes that case a lot easier to manage.

I don't use stash for cases where it doesn't make sense. I use stash for cases where, for me, it makes sense. For a special set of config changes that are never pushed. They're not part of my usual work, they're config changes. In this context, your 2nd paragraph makes no sense. I don't have to arbitrarily choose one or the other "workflow", I use both, and I simply use stash for the general case of reapplying configs on random branches. There are other ways to do it but they all require more headspace and are harder to track than stash and stash pop.

I'm not saying I need to stash or that I can't do it without stash. Have you not seen my earlier post?

It has nothing to do with being comfortable with commits. I'm already comfortable with commits. I've even said, before, that I did it with commits. It's just slower to do it with commits, and it means I have to manage commits for something I'll never, ever push. Every time I make something a commit, that's extra work for me later to make sure I don't push it out. If I make commits after that commit it's extra work for me to rebase it.

I don't put things in my stash where I care about a bad merge with them or that I'm even going to bother searching for the blob, I'll just redo the changes if that ever happens, because they're minor. They're things like: "Point to my database instead of the standard dev database". I just don't want to do them by hand every single time and I don't want to track a hash that changes every time I actually do want to change my configs.

You're the one making a big deal out of something, honestly, and you do not seem to be reading my posts very carefully because you're still making a lot of incorrect assumptions.


> You're the one making a big deal out of something, honestly, and you do not seem to be reading my posts very carefully because you're still making a lot of incorrect assumptions.

I'm sorry you feel like I wasn't listening to you. I was, and I read all your posts. You're absolutely right, I have made a big deal out of it. Despite the long discussion, I think we're in nearly full agreement, and FWIW, thank you for engaging.

I did misread your pull --rebase comment. I thought that was sorted now, but I'd be happy to address any other bad assumptions I'm making. It wasn't clear to me until just now that your config changes are small changes you never push. If you stated that before, I'm sorry.

Given your use case I agree with you, this is not an either-or proposition. And anyway, it's perfectly fine to leave all of this as my stupid opinion, and I don't want you to feel like you need to defend your use of stash. You clearly understand the issues and know how to use it.

In my mind, the only thing wrong with stash is how it's implemented, not its interface. I wish it had easier ways to recover, and I bet you did too that first time you used it.

Maybe the funniest part of this is I've been avoiding stash completely for years, but the threads for the last two days have convinced me there are some nice uses of stash that I may start adopting. A couple of them even increase safety! I do keep config changes around, and I like to name them with a tag or a branch, but I'm going to try stash and see if I prefer it.

Peace!


Well, I said at the very beginning:

> But that the thing - I never stash crucial code, just things like settings that are special to me and not other developers, so they'll probably never be pushed.

I don't know if that wasn't very clear.

Nothing wrong with opinions, there's a reason we share them, and I agree that stash could have probably been implemented a better way underneath. I have been recommended to use stash by another developer without any sort of warning, and with the implication that it's really safe and easy to use, which is rather funny in retrospect. Git's documentation page doesn't really talk about the dangers, either.

> Peace!

Indeed!


> $ git commit -am "config changes" > $ git checkout Y > $ git cherry-pick X

Sure, but then I also have to do:

    $ git checkout -
    $ git reset --hard HEAD~1
    $ git checkout -
which is a bunch of faff compared to the stash approach.

(side complaint: why doesn't "-" work for merge/cherry-pick/reset like it does for checkout?)


Huh? I don't get what you're doing there, or why you reset unstaged changes 3 times in a row... If you're trying to get rid of a commit, a single reset --hard will do. But why are you trying to get rid of a commit, and how is this more work that using stash? If you have unstaged changes you don't want, you have to reset either way, this is orthogonal to comparing stash vs no-stash workflows.

> why doesn't "-" work for merge/cherry-pick/reset like it does for checkout?

I don't know what a single dash does for you. On my git, I get a command line error with a single dash. Maybe you were thinking double-dash?

A double-dash is used to separate flags to your git command from path arguments, just in case a file you put on the command line starts with a dash. (Pro-tip: don't name files that start with dashes.) Running "git checkout -- ." at the top level of your repo will do the same thing as "git reset --hard HEAD".

Merge, cherry-pick and reset all work on refs, not on paths, so when you add a -- to one of those commands you may get an error like this:

  fatal: Cannot do hard reset with paths
The -- is optional to checkout, if the path is unambiguous. You can reset unstaged changes from your repo root by using "git checkout ."


> Huh? I don't get what you're doing there, or why you reset unstaged changes 3 times in a row... If you're trying to get rid of a commit, a single reset --hard will do. But why are you trying to get rid of a commit, and how is this more work that using stash? If you have unstaged changes you don't want, you have to reset either way, this is orthogonal to comparing stash vs no-stash workflows.

I accidentally made changes while on X when I wanted to make them on Y. I don't want to just "git checkout Y" in case that conflicts. If I do as you suggested and commit them (on X) and then cherry-pick that commit onto Y, I then have to go back to X to remove the commit I made, otherwise I have the changes on X as well.

> I don't know what a single dash does for you. On my git, I get a command line error with a single dash

"git checkout -" switches to the previous branch. Which is great, but it's frustrating that I can't do e.g. "git merge -" to merge the previous branch - logically that should be the same kind of thing.


> "git checkout -" switches to the previous branch.

OH, that's very nice, I want that. Guess I need to upgrade my git. Okay, that invalidates my entire previous post. Sorry! ;)

So, if you made changes on X but wanted them on Y...

The thing about the "git checkout Y" is that there's no harm in trying, and it'll work most of the time. If it does work, you only have to commit, and you're done in less time than it takes to stash & pop.

If you're just not the gambling type, here's one way to avoid branch ping-pong. I'm sure there are others.

  $ git checkout -b Z
  $ git commit -a "config changes"
  $ git checkout Y
  $ git cherry-pick Z
  $ git branch -D Z
I admit that's a tiny bit more work than with stash, in this case, but it's safer than stash, that's why I prefer it and advocate it. It is demonstrably harder to screw up if bad things happen in the middle. This workflow is also more general - you can use it if you have commits in X already. Stash doesn't help you there.

I've personally witnessed too many stash accidents. BUT, if you are comfortable with using fsck if anything goes wrong, you really have no reason to consider my opinion at all.

I'm painting a picture that is more anti-stash than I actually am. My main safety concern with stash is how it's implemented, not how easy it is. The git authors could have used something like the above commands under the hood to implement stash, but they chose to circumvent the reflog for reasons I don't know, and that choice leads to frequent accidents. Git is supposed to be your safety net, not something that gets you into trouble.

That said, a lot of people seem to think stash is many times easier than the alternative, and I think if you really look at the alternatives fairly, using commits is most of the time not more difficult than stash, and occasionally one or two extra commands. It's just not that hard to avoid stash, and there are significant benefits.


What's the way that one screws up with stash that doesn't happen with other approaches? I don't think I've seen stash accidents, though most of my colleagues don't seem to use stash much. If an attempt to pop conflicts, can't you just abort it?


I wish git would deprecate stash and replace it with something like this, that doesn't have any magic and just uses the existing branch system.

It would generate a new temp branch every time using a counter system, e.g. "stash1" "stash2", so all the temp branches effectively form a stack. The stash popping behaviour can still be supported this way (popping would cherry-pick and delete the highest numbered branch).

It would be easy enough to script as a side project too.


Yeah, exactly. I don't understand why stash wasn't done this way. They didn't have to circumvent the reflog, it was a choice, and one that bites a lot of people.


> You only need to commit or stash if there are conflicts

Unless you're wanting to take a look at the other branch clean, then you have to stash or do the extraneous commit. Most of the time I change branches to check someone else's work, or compare something that isn't working to develop/master. The stash/commit dance is a regular annoyance for me


This is true, you have to stash or commit, if you want to go to another clean branch.

But, your code is going to be committed & rebased later in your own branch anyway, right? If you commit some partial changes & later come back, make some more commits, and rebase/squash before pushing, you haven't done anything extra you wouldn't have done anyway.

By stashing, going away, then coming back, popping, working, committing, rebasing & pushing, you've added extra steps to the general case by involving stash, and you've added an extra failure point. If you commit instead, your changes are already there when you come back, and they stay associated with your branch while you're gone. It's harder to forget what you were doing, and it's much harder to lose your work accidentally if you commit.

I've witnessed the exact scenario you describe go bad several times when people go code review or test someone else's code, and the forget what they were doing. Sometimes people will stash again while working in someone else's branch, making it hard to keep track of which stash is which. That can lead to accidentally dropping stashes, or to popping the wrong stash.

Try only using 'git commit -am "WIP"' as a git stash replacement for a while and see if it really is any harder than stashing. To uncommit a WIP commit (which is always optional -- you could wait until you rebase -i) just 'git reset --soft HEAD^'.


> I'm forced to either make an extraneous commit, just to enable branch switching

Which you can later squash via interactive rebase.


gitless gives each branch its own separate worktree (see `git worktree`), and saves/restores them when you switch branches.

Also, there's no harm in creating "temp" commits. If you are having multiple branches, you probably want to give your current state a name - which is what a "temp" commit is.


Just use the normal git fallback command


me nor my web search engine never heard of it


Perhaps m3kw9 means that if there's something that you can't do in Gitless, you can fall back to the Git way of doing it, since both use the Git plumbing.


> Both of the solutions above are really cumbersome and prevent easy context switching.

Too frequent context switching might actually be perjudicial for your productivity and health, while increasing stress levels. So git not making it trivial might not be a bad thing, in my opinion.


I don't think perjudicial is a word.


Just a misspelling of prejudicial


you are wrong


It seems to be a word in Spanish. It isn't a word in English.


prejudicial is absolutely a word in English. look it up


But "perjudicial" is a word in Spanish, meaning "harmful", "detrimental". I think that was the meaning intended.


Thank you.


To me the really bad thing about git is its command-line interface.

It has extremely verbose messages (writes out a lot of stuff that you don't need to know) and common use cases often requires multiple steps (ie. add, commit, push if you just want to send a change from your work machine a github repository).

Compare this to subversion which is much less verbose, and in general just have one operation pr. use case.


Not sure why this appears to be been down voted. Git's command-line interface IS terrible. Certainly not unusable as most of interact with it every day.

A somewhat satirical example of this is Steve Losh's Git Koans.

http://stevelosh.com/blog/2013/04/git-koans

That's not to say I don't think the underlying ideas of how Git works makes sense. I certainly think it's a lot better than RCS, CVS and SVN (never tired Mercurial).


Love it! The hobgoblin one should mention "deleting a remote branch" in contrast to deleting a remote and deleting a local branch.


I realize that Hacker News generally frowns on "+1" types of comments. But those Koans are really funny. Every single one made me laugh out loud. I remember the pain of git.

I hated git. Every time I used it I wanted to curl up in a soft, warm, dry space... like Perforce or SVN.


I disagree. It's one of the best command line tools I've seen. It detects errors, gives you suggestions and you can get along with a few basic commands. Yes, there are multiple steps, but that's okay because it can't figure out your intentions.

Look: http://imgur.com/xY8dKWD no verbosity here and this is 99% of my git workflow. Working in a team is more tricky, but you should use and IDE with built in git support.

If you want to see a bad command line tool, try FFMPEG.


This is not objective. Git CMD has terrible flaws that are easily spotted as soon as you start teaching git, because you can see people struggling on difficulties purely created by a bad design.

As a professional trainer, here are the most commong problems:

- git checkout does so many different things. Git check file, git checkout branch, git checkout commit all do different stuff, and don't get me started on the option flags.

- git is context dependant. If you don't know the context, espcially the state your repo is in, you will struggle. And nothing in the tool gives you enough context if you don't explicitly ask for it, which supposes you need to know you need it, and what "it" is.

- branch switching is a hard. see article.

- stashing is dangerous. I've seen many students loosing work with a stash pop requiring a merge which ended badly.

- the whole syntax is impossible to discover, even for very common tasks: git checkout HEAD^ /file/path, git rm --cached, etc.

- git assumes you know what you are doing. Which means it let you destroy history with rebase, loose stuff with stash pop, create detached head, make force push, and all it all put yourself in many situations a beginer won't understand, and above all won't need.

Now I don't blame git designers for those. They made the tool they wanted to use.

What we need is a good UI on top of that. It can solve 99% of those problems.

The github one is not so bad compared to all the ones I tried (yes I tried yours), but it's still not it. What you need is someone that look at the most done tasks and questions, and provide safe, fast buttons for that.


> - stashing is dangerous. I've seen many students loosing work with a stash pop requiring a merge which ended badly.

Yes!! Stash has a problem that it's attractive to beginners, and its easier than other commands to hose yourself. It's a separate system for managing changes outside of commits, I don't get it. They could have made shortcuts to branch & commit. Mystifying.

> What we need is a good UI on top of that.

Srsly. But, wouldn't having a consistent & clean command line interface enable that? I haven't seen a good git GUI yet, they are all crippled because they stick to git's terminology. None of the UIs have been able to escape the foundation of the git command line, and I'm starting to think it's not possible.


> Yes!! Stash has a problem that it's attractive to beginners, and its easier than other commands to hose yourself. It's a separate system for managing changes outside of commits, I don't get it.

It isn't a separate system "outside of commits". Stashes are literal commits. If you were to write a script that made little WIP commits it would probably end up looking a lot like git-stash (which is literally just a shell script wrapper around other git commands).


Sure, except stashes aren't in the reflog, so they are "outside of commits".


> - stashing is dangerous. I've seen many students losing work with a stash pop requiring a merge which ended badly.

I've seen this assertion before, I don't understand it. If `stash pop` has conflicts and it gets confusing, you can always just `git reset --hard` and `git stash pop` again. The stash does not disappear if there are conflicts.

The only time you can lose data is if you explicitly `git stash drop`. So don't do that. And even then, the data is sitting in the git repo and can be recovered with `git fsck`. It's really hard to lose data with git.


Having just been in this situation, I think you are missing the problem. The problem is that after "git stash pop" has conflicts, the user does not know the state that of the system, and thus does not know how to react.

In my case, I temporarily changed a number of tracked "build" files that are custom my system and that I do not intend to check in for others to use. I was then asked to test a branch that someone else had checked in. My desire was to stash my local changes, check out their branch, and reapply my local changes to build it. But after "git stash pop" failed I had trouble figuring out the state of the system. I couldn't make any sense out of the messages that appeared, and fell back on Googling for answers.

My expectation was that the stash would have been popped, that I would open the build files, find some lines about merge conflicts, that I would manually fix them in an editor, and then I would rebuild. Instead, it does "something else", and hard part was figuring out what that "something else" was. There are probably excellent reasons for the exact behavior, but I'd ask: where is it made clear to the user what happens when "git stash pop" experiences conflicts? Where does it say to do what you suggest?

Separately, if you happen to know, how should I best deal with this personally frequent situation that I have a small "patch set" that I want to be able to apply to arbitrary branches, but that I have no intention of ever making visible to other users? I'm sometimes tempted to fall back on "git diff > patch.local" and manage it manually, but there must be a better way.


  > git is context dependant
In particular, git violates the universal *nix convention that you can operate on a file using a full or relative path regardless of your current directory.


>What we need is a good UI on top of that. It can solve 99% of those problems.

It's called magit.


And then you have 2 problems.


>git checkout does so many different things. Git check file, git checkout branch, git checkout commit all do different stuff, and don't get me started on the option flags.

I'm curious, how would you redesign git checkout to handle each of those different types of inputs? For me, while it appears cumbersome, understanding that a file is different from a branch and commit head seems to alleviate this problem.


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?


> 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

> 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?


Sure 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.


> it tries to hide the index and thus encourages bad habits in git users.

I'm curious what you mean by this. What are good & bad habits wrt the index?

It makes sense the index is there for conflict resolution, and it seems really convenient for interactive adds & rebases. But I could imagine implementing those things without having an explicit staging area. Are there other more important requirements for the index? It mostly seems like a convenience that it's exposed, but not something that provides either more safety or better practice.

Many VCSs that predate git don't have an index because they don't need one, and having one wouldn't encourage better habits. Git has an index and rebasing almost entirely as a result of it's strict enforcement of lineage, which older VCSs didn't have. In Perforce you can create and manage multiple changes before you push, and you can push them in any order. Because git enforces order, it basically needs rebase and an index to make using git sane. In that sense, these things can be seen as a UI disadvantage over other VCSs. Of course we know there are much bigger advantages that come with strict lineage, so we learn to stage, rebase, etc.

What other benefits does the index provide that I'm missing?


> stashing is dangerous. I've seen many students loosing work with a stash pop requiring a merge which ended badly.

`pop` will no longer drop the stash if there is an error applying it; it did in the past.

There is a point where it is worth having at least one person on a team study the internals of Git vs. struggling with it constantly and possibly losing work---it will save time, energy, and work in the long run.

In the stash case, `git reflog` would immediately allow you to recover the lost stash. If you're in deep shit, `git fsck` is valuable until the commits are GC'd. Even if you don't remember the commands, you'll know where to look for them, or what to search for to find it. Or even understand that it's _possible_.

> nothing in the tool gives you enough context if you don't explicitly ask for it, which supposes you need to know you need it, and what "it" is.

There are numerous PS1-augmenting scripts available; git even comes with one. But I agree that it otherwise would be incredibly frustrating for beginners.

> branch switching is a hard

I've heard many criticisms when watching others learn Git and teaching others, but this is one of the only things that never comes up once they've done it a couple times. Stash and switch. Or commit WIP and switch.

> the whole syntax is impossible to discover, even for very common tasks: git checkout HEAD^ /file/path, git rm --cached, etc.

I learned pretty much everything I know about Git from experimentation and, most importantly, the manpages. If someone is unaware of manpages, the documentation is online. Failing to read is failing to discover, yes.

> git assumes you know what you are doing. Which means it let you destroy history with rebase, loose stuff with stash pop, create detached head, make force push, and all it all put yourself in many situations a beginner won't understand, and above all won't need.

Yes, this is fair. But also essential. I have recovered from more fucked situations that I could have imagined, and have helped others do the same---situations where I would have otherwise lost work.

But it's a matter of teaching someone fallbacks. If you accidentally screw up everything with a rebase on <branch>, `git reset --hard origin/<branch>`. If you can't remember that, open tig / gitk / a web interface / etc, find the hash, and reset to it. If you are on a detached head, check out a branch. You shouldn't be force pushing, but that's nothing the manpage can't help with.

It all comes back to the basic understand that nothing is ever deleted in Git until garbage collection. There is always a hash to recover. Sometimes I just lazily scroll up in my terminal and grab it.

But your first point:

> git checkout does so many different things. Git check file, git checkout branch, git checkout commit all do different stuff, and don't get me started on the option flags

Yes, this is unfortunate.

tl;dr: Research your tools! Poke around the manpages or online. Know what you don't know so that you know where to look later. And there is always e.g. gitk to fall back on for certain things---I see others on my team do that as well.


This is a great post! I have only one minor point:

> In the stash case, `git reflog` would immediately allow you to recover the lost stash.

Stashes don't go in the reflog, you cannot recover them with git reflog, so you're automatically in the 'deep shit' category if you lose them. Hence the statement that stashes are dangerous.

You do still have the safety net of fsck, and knowing that it's possible matters, as you point out. But, my experience with people who mess up stashes has been that fsck is so intimidating they'd rather re-create their changes. Silly, but true.


> Stashes don't go in the reflog

You can see them with `git reflog --all`.


Not after they're popped or dropped. Only while they're in the stash list.


The thing is, once you learn the UI, it's very productive. I'm not sure we should be optimizing for ease of learning. People are only beginners for a little while. They spend much more time as intermediate/advanced users.


This really depends on how frequently and how deeply you use git. If you're using many of its advanced features a lot, then yes, you'll probably learn it well just by doing that.

But many people don't use it very deeply most of the time, and only occasionally have need to do something out of the ordinary, at which point it can be a pain to discover the Right Way to do what they need, and easy to shoot themselves in the foot.


FFMPEG is a case of a tool trying to do too much, although, trying to break it out into separate tools would probably be worse.


Ffmpeg isn't a tool. It's a library to be used by programs who work with video and audio files. It has lots of features because different applications need different features.

The ffmpeg command line program is basically a demo that exposes every one of those features directly. Having it "do less" would defeat the point.


The progress displays for pushing and fetching are a bit verbose in my opinion, but otherwise I mostly agree.


You don't think that the "git push" output includes a lot of verbose tehnical junk not meaningful to most users?


Not really, while I'm not sure what 50% of that means, it's just reassuring that after push I see that 5 lines and a percentage counter. I can also copy the commit hash and refer to it in a ticket.


The first 5 lines in that image could be replaced with a simple progress bar and no one, except for git developers, would lose anything worth keeping. That stuff in a normal CLI tool would only pop up if you use --verbose/-v, it's almost irrelevant to the average user.


Or the original syntax for tar


Obligatorily: https://m.xkcd.com/1168/


It's simplicity and ubiquity are the only reason we keep seeing absurd programs like Gitless put forth. Imagine if someone came out with someone that "fixed the warts of QT" that was just a wrapper around QT. It's a joke.

It's coffeescript vs javascript all over again and we saw how that played out.

Don't like how git works? contribute. Don't make some stupid command line utility that just adds another entire layer of abstraction on top because people don't want to take an hour to read about git internals.


Now, this is a UI problem, you don't need to change git, you just need something higher level.

Git is fine the way it is, but it targets power users. Most people don't need that power.

In that sense, gitless has a proper approach even if I don't like the result.


I tend to agree with you that most people don't need that power but I think the problem is just that it IS a CLI interface, not that it's a particularly bad one. A GUI is the perfect tool to deal with discoverability and providing an easier interface for non-technical users. A CLI wrapper is just making things more confusing. I don't really understand what problem gitless seems to be solving...


I disagree; `hg` is a CLI as well, but it's far simpler and safer than `git`. That said, I have far more experience with git than hg. Further, gitless itself is a cli, and it's also simpler than git.


I have experience with both daily, and I mostly just don't notice any meaningful difference. Especially with the bookmark extension.


If simplicity was the goal of command line interfaces they wouldn't exist. This is not ls or cat, nor is it trying to be. hg might have a better CLI than git, but it still doesn't justify something like gitless.

You need a really compelling reason to layer another level of abstraction on top of git and from what I can tell, having branches be full sets of working files isn't really a good enough reason to make that switch.

Where are the improvements in Gitless exactly? Pretty telling they don't even list them in anywhere.


The CLI is indeed hard to learn. But the simplicity of git is not using it, it's its internal structures:

http://eagain.net/articles/git-for-computer-scientists/

If you understand these, then three stages to "commit to server" won't seem too many to you. (Often you don't need the index-building stage ("add"), and then you can say "git commit -a").

What people complain about is often the CLI's inconsistency. For example "git branch -d" vs "git remote rm" to delete things. Then some things you want to do can be achieved with more than one sub-command in totally non-obvious ways. And some sub-commands do more than "one thing", like "checkout".


You shouldn't have to learn how the data structures of the tool work beneath the surface to successfully know how to use a tool.


I think you should learn them, but ideally it should be obvious from using a tool what its internal data structures are. For persistent data structures simplicity, transparency and stability are very important.


You don't have to. The difference with git is that it's even possible.


Why wouldn't it be possible with Gitless to learn the data structure?


Common use cases require multiple steps because that's how it's meant to be. Staging (adding), committing, and pushing are three fundamental operations of Git that, when combined in different ways, produce many use cases. Personally, I would rather have these operations exposed to me rather than having to memorize (or worse, have to search up) a different command every time for each use case.


My pet peeve is how many steps it is to resolve a merge conflict on a branch I've pushed when were using controlled merges into dev branch. Stash or commit my work on the new feature branch I've started, then switch to dev, then pull, then switch back to my old conflicty feature branch, then merge from dev and resolve the conflicts, then push, then go to the server and complete the merge, then switch back to my old stashed branch so I can get back to work.


No need to switch to dev:

  git co feature_branch
  git fetch origin dev
  git merge FETCH_HEAD


I think part of the issue here is that the actions one wants to take isn't the same for everyone.

For example, I basically never want to commit and then immediately push to some server.

And for add, then commit, you can just do git commit -a.

But being able to add and commit changes separately can be very useful.


Well:

git commit -am "message".

Will add and commit. Pushing should be separate for a distributed vc.


You can create aliases to execute multiple commands at once.


But why should each developer need to do that on each system they use?

The whole point of this tool is to add a common set of things on top of git.


I don't see why each developer should. I'm perfectly fine with commands as they are by default.

I'm just saying that if your problem is that you need to enter multiple commands instead of one, then instead of new VCS you may as well just put a config file in your home dir.


This isn't a new VCs though, its a layer on top of git.

You can still use all git commands.


Yea the Git CLI is a giant pile of steaming shit which is probably why there are plethora of visual tools for working with Git instead.


See also discussion about the Gitless paper: "Purposes, Concepts, Misfits, and a Redesign of Git"

https://news.ycombinator.com/item?id=12612333 (1 day ago, 106 comments)


And it hits the most important point of: Gitless tries to do away with the staging area, thus completely misunderstands Git.


It seems more plausible that Gitless just disagrees with its utility, or at least finds dancing around it overly cumbersome for the default case.


I've been using git for a few years, and often wished I could eliminate the staging area. It's an extra step for every commit, and creates extra complexity for no benefit I've been able to see. I haven't seen a practical example of a use case that's improved by having separate add and commit.

By your statement, I also completely misunderstand git. That's entirely possible, but if git is so hard to understand that daily use for years doesn't lead to understanding, maybe it's ok to misunderstand git.


> I haven't seen a practical example of a use case that's improved by having separate add and commit.

Well, I frequently see random things to fix while I'm working on a problem.

When I 'm ready to commit, I run `git status` and notice there's a file that's been modified that's unrelated to what I'm trying to commit.

A quick `git diff` later and I see what I did: fixed an unrelated issues. So I add that one file to the index, commit it with a relevant commit message, and then proceed to do a second commit—the one I had expected to do—also with a relevant commit message.

I do this 3-5 times a day, at least.


>there's a file that's been modified that's unrelated to what I'm trying to commit

What if those unrelated changes are in the same file as a bunch of related changes that you've already made? Do you undo all the changes you've made in that file apart from the random bug fix and then commit, or leave them intact resulting in that bug fix commit containing changes that are unrelated to the fix?


In that case you'd want to use "git add -p" which allows you to pick only parts of a file to stage for a commit. It can be crucial in crafting a really solid project / commit history.

For even more complex cases you could use "git add -i"; however, that command can be tricky to work with and I find it's usually not to helpful to get that far into the weeds.


Atlassian has a nice UI for doing that visually, too. Super easy.

Honestly, people for whom the command line UI is "too difficult" should just use a GUI client. That's the target audience for them.


I do this kind of thing often too. To me this all seems like it could be handled at commit time. And more simply too.


How do you know that they misunderstand it, as opposed to disagree with it?


Please refer to the linked discussion.


Okay, I referred to it again. Still not seeing where you know that they misunderstand it, as opposed to disagreeing with it.


I've been using git professionally for a few years, and other distributed version controlling systems for more than a decade. This is the first time I see the phrase "staging area" in relation to VCS. Could you explain why it's an important concept?


It's central to git. 'git add' puts changes in the staging area. Then 'git commit' commits the staged changes.

The staging area is also known as the 'index' and the 'cache'.

(Git has a consistency-of-naming problem.)


> (Git has a consistency-of-naming problem.)

I wonder how many git usability issues could be solved just by addressing this and this alone.


Please refer to the linked discussion. Various people ask about it and various people try to explain it (including me).


I don't see any improvement over git. Just another set of commands you'll need to learn from scratch. Some ideas seem not very good, like committing all changed files by default. If you find git commands too verbose - try 'tig' - the ncurses git client, it saves a lot of time and efforts being simple and straightforward at the same time.


wildly guessing from the clone to checkout name change, it probably started as a git for subversion users?


Removal of the staging area seems like a move in this direction too.


In my experience, making "gl commit" equivalent to "git commit -a" seems like a bad idea. When leading a team, especially of newer coders, one of the most effective ways I've found of keeping the git logs and the code base sane more generally, is to force people to review their own code at the time when they commit it. Individually adding each file with "git add -p" achieves this, and "git commit -a" squashes it.

Reading the methodology used to develop gitless yesterday was interesting, but if I recall correctly, I think it left something out. They looked at how often a software design allowed users to complete their intention, but the tool ideally not only should allow users to complete their intention, but should encourage users towards practices that increase the quality of the end product. While people may struggle with staging at first, I think it in the end encourages better software, which is my biggest concern.


I am also pleasently surprised by this initiative.

I consider myself an advanced git user so I am not sure I would use it myself, because my brain is hardwired to git's wicked commandline interface now. There is little that surprises me in git nowadays.

I am used to give out simple "the 10 git commands you will ever need" tutorials to people, but it's true that it is confusing for people, even with that. gitless takes out significant confusion out of the daily grind of using git, so much that I may end up recommending it instead of git itself, especialy since they are interoperable.

What I would love to see would be to have those commands percolate back into git itself. git's usability has improved significantly since it started, and while this project shows there's still a lot that can be improved, history has shown us that git can be improved. track, untrack, history, switch, resolve, publish, init's remote argument, all those could be added as commands into git and equivalent commands could be deprecated or just kept for the hardcores like me that don't want to be bothered learning a new simpler interface.

Unfortunately, given the reaction on the mailing list, I am thinking this will not/never happen and gitless will remain a friendly fork: http://marc.info/?l=git&m=147527432403442&w=2


In this thread, lots of people wanting to demonstrate their deep knowledge of an arcane tool, thus proving the whole point.


Posted this upthread, but here's an apt Linus quote:

> The first Git For Dummies and Git Visual Quickstart books are going to be out in a couple of months, and that is the beginning of the end as far as I’m concerned. Those books mean the end of git expertise and github reputation as reliable indicators of geek status. Once a technology is adopted by the masses the extreme geeks find something more esoteric. Look at what happened to Ruby on Rails. The people stumbling their way through Rails to-do list tutorials have never even heard of DHH.


That sounds like a very elitist approach. So the technology is good as long as it's arcane, but as soon as it becomes mainstream then it's "the beginning of the end"?

...do we even need a "reliable indicator of geek status"?


It is not a quote by Linus but part of a satirical piece, see:

http://typicalprogrammer.com/linus-torvalds-goes-off-on-linu...


My criteria for whether an interface to git is truly easier is whether artists can use it. I've worked in games alongside artists, with everyone using Perforce. At some point we switched to Perforce for the art, and git for the programmers, with a big janky glue system in-between.

Git couldn't really handle all the binary assets, and the artists couldn't really handle git, so it made sense. When we switched, it also took a long time before the programmers could really handle git too, fwiw.

I've long said I'd love to see something that's as nice a GUI as p4v, but with git under the hood. I haven't yet seen a git GUI that even approaches now nice p4v is, and git on the command line, once you learn it, is the best interface to git hands down.

I can't tell, but does gitless look like it could make a simpler gui to anyone else? I love the idea of gitless, I'll have to try it, but I get the sense that I'd end up needing to switch to git for some things.


As far as version-controlling art, I'd lean towards a system where checking a file out locks it from any other concurrent modifications. Unfortunately, trying to merge concurrent changes into an image file, for instance, is just about impossible.

It's almost as bad trying to work with MS Office file types - I wish I could get people on my team to use something else that is more VCS friendly, like HTML or Markdown, but that's an uphill battle. Even better would be if we actually used the versioning and collaboration features that are built into some of the tools like Office 365 that we pay for, but can't seem to leverage...


My wife is a math teacher and trying to figure out a good workflow for her team has been illuminating. Only the one true desktop Word has a good formula editor, so they have to use that... and only SharePoint provides a good "open and save" workflow. So SharePoint it is. Anything to get them off timeshares.


Ick, fileshares. Autocorrect.


Yeah, exactly. Perforce has file locking, and the need to file-lock binary assets is a great example of why a central server setup has advantages over a DVCS in some cases.

The alternative to file locking could be a rule set for who or which branches win when there are conflicts in binary data. Then again, as an artists you would rather know if someone's touching an asset before you dig in. With art & binary assets, it's more important than with mergeable code that your team and work is properly organized in a way that avoids multiple people touching the same file.


Re. GUIs for git, have you taken a look at GitKraken [1]? I haven't had the chance to put it through its paces, but it looks pretty good.

[1]: https://www.gitkraken.com/


I have. I've used all of the git GUIs. None are as good as p4v as far as a GUI goes, and none are particularly usable by artists. Especially powerful in p4v is the timelapse view, which nothing in any git client comes close to approaching.


I recently switched to GitKraken from SourceTree. SourceTree has better features and workflow, but SourceTree performance is very VERY terrible. I'm talking 2+ minutes to wait for some operations to complete.

Not sure why GitKraken makes it so hard to add remote repositories and doesn't allow auto-push, and other niceties. But I use it for normal checkin / branch switching workflows and it's great.


Applications are open for YC Winter 2024

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: