Hacker News new | comments | show | ask | jobs | submit login
Legit. Git for humans (git-legit.org)
361 points by andybak on Mar 25, 2012 | hide | past | web | favorite | 131 comments

Like anything else in software development, the hard part to learn is the abstractions, not the syntax. People struggle with git because it's an immensely powerful tool. "git reset" has quite simple syntax, but it confuses the hell out of even experienced git users because it's very clever and potentially very dangerous.

Of the altered syntax in Legit, "switch", "sync" and "publish" make sense, but "harvest", "sprout" and "graft" are no more intuitively obvious than the git equivalents.

I found that the syntax _was_ the hard part of git. That and the often-terrible man pages. Both docs and syntax are inconsistent, verging on random, and full of irrelevant details. It's pretty hard to figure out the actual concepts beneath all the noise and misdirection.

the git vs EasyGit diff basically summarizes what I'd change about git.

I'd be curious to see a few examples. Git is guilty of using a bunch of non-standard nomenclature, and of using existing terms in non-standard ways ("checkout", I'm looking at you). But I certainly wouldn't call the interface or syntax "inconsistent" or "random". It's actually very tersely designed and very well put together. The "actual concepts" are, for the most part, first class citizens in the interface.

> But I certainly wouldn't call the interface or syntax "inconsistent" or "random".

Uhm, NO WAY.

git checkout works on both branches and files.

I can `checkout remote-name/branch` but I have to `push remote-name branch`. Deleting a local branch is `branch -D` but deleting a remote branch is (I still can't fucking believe it) `push remote :branch`. It's surprisingly hard to unstage a file.

If a rebase fails, it gives you exactly one warning and then forever complains about a dirty index tree. The error messages are borderline incomprehensible for someone who doesn't understand git internals (refs/head say what?). The reset command is far to easy to typo into oblivion.

What else. I haven't spent a lot of time thinking about it, but obtaining an exact list of differences between branches is hard (git `log sha1..sha1` compared with `git log sha1...sha1`).

This is just off the top of my head. Git is great, it's fast, I don't understand people who are still on svn, but the user interface is abysmal.

Git checkout is actually pretty consistent and only really works on branches. When you say it works on files, you actually mean it has a shorthand that works on files:

  git checkout my-file
... is actually using a lot of smart defaults. Namely, you're actually running ...

  git checkout HEAD -- my-file
If you don't specify a branch or identifier, git uses HEAD by default in most cases. (When you run git diff other-branch, you're actually running git diff HEAD other-branch.) And the dash-dash syntax is mostly optional in modern git.

Not inconsistent at all, as far as I can tell. In fact, most features of git that I use on a regular basis are completely consistent and orthogonal. The exceptions are submodules and remote cache branches...

So, in the end it worked on a file. :-)

It worked on a branch, filtered by a file name. I think that's an important distinction. That distinction unifies the definition of `git checkout`.


But it doesn't lead to an obvious, consistent command syntax, and that was the point.

It's a consistent syntax with smart defaults you can leave out. You wouldn't say Unix's wc is inconsistent, would you, just because it has default behavior?

Apples to Oranges. wc is a bad example.

Better example is tar vs cp, where you go

  cp files you want to copy destination/

  tar destination.tar files you want to archive
And yes, I would say that's inconsistent.

hum... both are wrong.

wc is "word count" it's not a sane default. it's a obviously explicitly behavior. if git checkout were called 'git checkbranch' then you would have a point.

tar does not have sane defaults. it requires explicit flags. your example (besides not working because as i said, it does not have defaults) could very well be `tar -c files you want to copy -f destination.tar` and all would be well. you actually still repeat the very first tar command line example you ever saw to this day, even not agreeing with it :)

> for someone who doesn't understand git internals

Looks like that's the difference. As someone who does understand Git internals, everything seems perfectly logical and consistent to me. Perhaps it's the same with the person you are replying to.

And really, using Git without understanding the internals is a suicide, quite a few people broke their repos and asked me to recover them. The internals are very easy to learn.

No. I should not have to understand how git works internally in order for me to use it.

This is called usability.

  > I can `checkout remote-name/branch` but I have to
  > `push remote-name branch`
So I can use the same command in svn/cvs to switch branches and publish changes?

  > Deleting a local branch is `branch -D` but deleting a
  > remote branch is (I still can't fucking believe it)
  > `push remote :branch`.
It's not that hard to understand. Most git commands only affect the local repo, but git-push and git-remote are used to affect the remote repo. It makes sense not to break that convention because some people feel it should be organized differently.

In any case, writing to remote repos was never part of the core design of git. It was designed to be a distributed group of people that would pull down remote branches, make changes, and then submit pull requests to the code maintainer (or use the various 'email patch' commands). Remember that it was developed with Linux kernel development in mind, where there is a hierarchy of developers responsible for sections of the codebase.

>So I can use the same command in svn/cvs to switch branches and publish changes?

No, it's about the notation for remotes and branches. It's confusing that sometimes when I refer to a branch I call it remote/branch and other times I call it remote branch. It would've been way more consistent if it were always remote/branch.

As a result, git push sometimes gets confusing. Suppose I'm on staging. I then say, git push heroku staging:master (push the staging branch to the master branch on heroku) whereas git push staging:heroku/master is imho easier to understand.

  > git push heroku staging:master
Without the shortcuts, this command would be:

  git push heroku refs/heads/staging:refs/heads/master
"refs/heads/master" is literally the branch location in the $GIT_DIR on the remote. You could do something like:

  git push heroku staging:refs/personal/phillmv/staging
to stick the branch in a non-standard location, or you could do:

  git push ssh://hostname/path/to/repo staging:staging

  git push ~pyre/work/repo staging:pillmv-staging
to push to a location that you don't have specifically defined as a remote.


  % cd /tmp
  % mkdir test1 test2
  % pushd test1
  % git init .
  Initialized empty Git repository in /tmp/test1/.git/
  % popd
  % pushd test2
  % git init .
  Initialized empty Git repository in /tmp/test2/.git/
  % git ci --allow-empty -m 'ini commit'
  [master (root-commit) 54ec2a3] ini commit
  % git push ../test1 master:test2-master
  Counting objects: 2, done.
  Writing objects: 100% (2/2), 168 bytes, done.
  Total 2 (delta 0), reused 0 (delta 0)
  Unpacking objects: 100% (2/2), done.
  To ../test1
   * [new branch]      master -> test2-master

Huh. Out of curiosity, why would I ever want to do this?

> git push heroku staging:refs/personal/phillmv/staging

Will it still appear in git branch lists?

I get what you're saying and I appreciate the lesson :).

Is there a reason for the syntax in checkout being remote/branchname then? I care about consistency more than the specific syntax.

  > Will it still appear in git branch lists?
By default, git will only pull branches out of refs/heads/* on the remote repo. You can configure it to do otherwise though. This allows you to store branches on the repo that not everyone will necessarily pull down into their repo. This is obviously less useful with a smaller group of developers and/or a private repository.

  > Is there a reason for the syntax in checkout
  > being remote/branchname then? I care about
  > consistency more than the specific syntax.
In git-checkout, you're resolving the branch name locally. When you sync to a remote, a copy of all branches from refs/heads on the remote repo are pulled down and stored in refs/remotes/$remote_name/branch_name. So, refs/heads/master on the remote repo is refs/remotes/origin/master locally.

The right side of the ':' in the git-push command resolves on the remote repo, but git-checkout resolves in your local repo.

Also look at the git-rev-parse manpage for info on the resolve order/etc for branch name shortcuts. It's the 3rd bullet point under 'Specifying Revisions.'

Yeah, deleting a remote branch by "git push remote :branch" is pretty terrible, one colon between heaven and hell.

If you understand how git push works, it sort of makes sense. But fortunately the devs added a --delete option to git push which is much more clear.

That is indeed clearer, thanks for the tip!

  It's surprisingly hard to unstage a file.
Is there a case when it's not a simple git reset my-file away?

Yes there is. When you have a new repository without any commits, there is no HEAD, so you can't unstage by resetting.

    mkdir try
    cd try
    git init
    touch file
    git add file
    git status
Still, the git status command shows you what you need to do to unstage.

Indeed no. That's exactly what git reset does: "copy entries from <commit> to the index". I got that from the unusably bad man page. It was the first sentence.

My question was a rhetorical one :)

I know. But you were needlessly agreeable. I thought some salt needed to be rubbed into the GP post.

And in every git status message.

I forget my exact edge case. Something to do with wanting to unstage a folder, or unstaging a folder while wanting to preserve work in some of the files.

> examples

    git tag
Lists tags; does not create new tag

    git stash
Stashes current changes; creates new stash

List tags/stashes:

    git stash list
    git tag [-l]

I agree with basically everything Elijah has to say here for example: http://people.gnome.org/~newren/eg/git-eg-differences.html

OK, I'm seeing where you're coming from. But I guess I don't see the severity. Yes, git's terminology is highly non-orthogonal (the umpteen different synonyms for the "index" was pretty amusing). But... that's just the frosting. Who cares how messy it is if the cake is still good?

Yes, it's messy. But I don't really see that it hurts comprehension. And it hurts learning only inasmuch as you can't guess at a command and have to check the man page (i.e. I know there's a diff variant that checks the index vs. HEAD, what's it called?). I can't honestly say I found it difficult to understand what the index was due to this.

An errant use of git force taught me that git is always logical, its just not always rational.

> "git reset" has quite simple syntax, but it confuses the hell out of even experienced git users because it's very clever and potentially very dangerous.

For anyone who gets a panic attack before running `git reset`, this talk may help clarify how things are working under the hood: http://www.infoq.com/presentations/A-Tale-of-Three-Trees

The only dangerous part of git reset is git reset --hard, which will blow away uncommitted changes. It has a special flag for a reason... it's dangerous.

Beyond that, git reset won't get you anywhere that you can't get back to after consulting the reflog

You can recover from a git reset --hard with the reflog as well, though of course if you had untracked changes you'll lose those. (I usually use git reset --hard in the process of renaming branches and not to get rid of untracked changes, so this isn't a problem for my workflow.)

This looks like it would be a nightmare for working with other developers.

Other developer: "I did 'git sprout foo' and made my changes then 'git publish foo'. But now I'm not sure why the foo branch isn't on the public repo." Me: "????"

While I'm perfectly happy with the stock git porcelein commands (and generally don't like any attempts at simplifying them, including gui tools) other developers having a different workflow isn't the reason.

I think having shortcuts and wrappers like the above is fine if you have a good understanding of the underlying data structure you're manipulating. You're only going to run into problems if you treat these commands as magic and just hope they work.

That's a terminology problem, not a design problem.

EasyGit, single script, very well thought out, longstanding tested project, doesn't "conflict with" or conceal the underlying git just fixes up the UI.

http://people.gnome.org/~newren/eg/ https://github.com/blog/333-easy-git

I second this, why not just use eg?

Looking at the commands, eg could have been substituted with hg

Switch, synch, publish, unpublish - those all made sense, but when they started adding things like 'sprout' and 'graft' it just passed into the realm of trying to be too cute with the branching metaphor for my tastes.

Personally, I'd pick git-flow over this. It seems more useful and makes, syntactically, more sense (though it can get a bit verbose at times `git flow feature start some-feature`). Starting and finishing features, hotfixes, releases, etc. handles all of the necessary branching, merging, and checkouts for you while adding structure and basically documenting the lifecycle of the code in your commit logs.

Maybe it's not as 'human friendly' as sprouting a branch, but starting and then finishing a feature sounds pretty straightforward.


Creator of Legit here.

git-flow is awesome. I use it every day.

This isn't so much of a branching model tool, but a tool that allows you to switch branches and interact with remotes very easily.

When you switch branches with Legit, any pending changes you have made are stashed automatically. When you switch back, they are unstashed. This saves me a lot of typing.

If you're following Vincent's branching model, switching from `feature/x` to `develop` happens quite a bit. So, they compliment each other well.

>compliment each other well


I welcome all attempts to create a better UI for git. Perhaps legit isn't it. Don't care. Eventually we will get this right.

I prefer git's internal branching model and few other features to mercurial but I really prefer the UI to git.

Keep it up people, eventually we will have a better ui.

All that said, I'd encourage people who are doing it, to not add the 'git' namespace. Create your own and just use the internals. Systems that add new 'git *' commands are just confusing an already confused situation.

They say it's for humans, but then explain the commands in terms of "normal git".

This'd made a lot more sense for me if they explain for what particular workflow it's intended and how to use it as such. With examples and all.

Maybe I should update it to "Git for Humans (that already use git)"

I just dislike the “for human beings” meme/fad.

1. It's casually dismissive of us cyborgs, who are too often marginalised already;

2. It's a subjective claim;

3. It claims you have taste that your competitors lack;

4. I've seen enough examples where my taste finds something inferior or seriously wrong with the design (not saying this is the case here) that I don't take these claims seriously.

Why not make it "Git for humans (that don't use git yet)"?

I strongly disagree with the purpose of this. It still has precisely the same problem that regular git has: you need to understand the language behind it.

Just learn regular Git rather than re-inventing the language.

I don't disagree with the purpose, the git CLI interface is pretty inaccessible to non-developers—more than it needs to be.

But you're totally right about the implementation. This just adds more commands under the git namespace, muddying the waters as much as providing a simple interface.

If the goal is to make git for mere mortals then what is necessary is to create new porcelain from the ground up and call it something other than git. That's a lot more work obviously, but git internals were defined to enable just that! Then in the fine print you could say "oh btw there's git under there for anyone that needs it". That's my idea, but maybe it would be better to just use Mercurial?

'porcelain' is completely new to me in this context. Could you explain what it means? (and who uses it?)

In more general terms, the 'porcelain' is the user-friendly interface commands, and the 'plumbing' is the internal commands.

With Git, it's often said that some of the 'porcelain' commands only make sense in the context of the 'plumbing' ones, and you should understand the internals first before being able to use the more user-friendly interface. It's things like this that lead people to create more friendly interfaces like Legit here.

"Porcelain" is git terminology for the user interface on top of the git low-level plumbing:


The same argument could be used with assembly language vs. Ruby/Python, but that doesn't stop people from using higher-level abstractions to get things done easily. They exist to streamline a process.

I see much ado about nothing in these comments. Is it really that awful to alias away an odd set of tools that sometimes contradict one another? That's what every high-level language does. That's what every decent UI does across any paradigm.

Abstractions make things easier for the human in many cases. If Legit increases the productivity of a team of developers and gets newbies using the Git VCS, more power to them and its use. They can learn the internals later.

> The same argument could be used with assembly language vs. Ruby/Python, but that doesn't stop people from using higher-level abstractions to get things done easily.

That's not the right analogy.

The situation here is more: you join a project that uses assembly language, which you find too hard to learn, so you decide you'll be using Ruby instead.

> you join a project that uses assembly language, which you find too hard to learn, so you decide you'll be using Ruby instead.

That's not my point. My point is that if legit gets people into using Git as their VCS, it seems silly to attack the idea because it isn't the current norm of engineering. Lessening barrier of entry to using a powerful VCS is not bad in and of itself. Not everyone jumps into assembly language. Plenty jump into higher-level languages and find themselves deeper in the rabbit hole as time progresses.

To a newbie, this legit script appears far more accessible than git's stock interface. Is it bad that GUIs exist because the command-line is often more powerful to an experienced user? Why is it so bad that this tool exists and can be used to increase overall engagement and entry into the world of Git?

The idea of a clean abstraction is you can predict what a particular operation will do without knowing its internal implementation.

For higher-level languages, this is generally true for the effect of a command: you can work out what a line of Ruby does without needing to think about the underlying assembly language. There are other abstractions (aka levels/layers), such as virtual memory, the OS and the implementation of the CPU itself in terms of architecture, transistors, silicon doping. (Sometimes these abstractions are said to still be "leaky" because to understand performance issues often requires knowing the underlying implementation - that's important but distinct from just knowing what it will do.)

A common criticism of git is that the abstraction is not clean - you need to know what it actually does underneath in order to predict that a command will do. It's not just a problem of an inconsistent UI (though it is that), but that the user model that the command sets out (the abstraction) does not match up with what git will actually do.

The OP's criticism is that legit (great name BTW) doesn't address this: people will use this simpler, friendlier UI, and inexplicable and weird dangerous things will happen (e.g. data loss). C++ might blow your leg off, but git can make you never have existed.

NB: I haven't looked at legit closely enough to tell if this criticism is valid (and OP offers no support - OP, please elaborate). I'm just clarifying the issue.

+1, If you just take 2 hours and read the entirety of progit.org (including the section on internals) all of these workflows on top of git start to look unnecessarily confusing.

-1, as a git user who finally submitted to learning the internals, I think this is not the right way to design software. I realize linux/et al are all geek inspired technology festivals, but to imply that a good User Interface and human accessible commands are unnecessary is... silly, the rhetoric reminds me of the elitist GNU/linux propeller heads back in 1999 who would constantly and derisively snort in disdain at "Windoze" users because they didn't know how to do a find / -name myfile.txt -print. Especially the one's who argued vehemently that the '-print' option made any sense whatsoever.

It's clear that you don't agree with the principles behind gits design. Why not use hg instead? It's a perfectly viable alternative and provides many of the benefits.

I have always seen git as a kind of assembler language for version control. We are now starting to see some second generation languages built on git. The first batch may not be perfect, but over time we will see improvements.

I welcome these attempts to abstract git and make it more accessible. I haven't yet seen one that I think I would prefer over native git, but am looking forward to see what develops.

It seems that git is the new regex. People are actively building things around instead of learning the rules. I suppose that came from writing being easier than reading.

I know regular expressions way better than most people I come across and I still never feel to good about my command of the more 'esoteric' features.

Having a version control system ( something that more people will use more often every day than regexes ) compared to them, is not a heartening thought.

Underneath, git is actually based on a really simple tree-of-objects data structure. All those esoteric features are built on an elegant base; understand that base, and you can understand anything git does (though it may not be obvious at first).

Well, regex has a horrible syntax too.

The mathematical principles underneath are good, but the standard regex syntax is arcane and values brevity over readability, modifiability, etc.

I don't want to venture too far off-topic, but when the Perl 6 folks re-designed regexes, they found out that they weren't really designed for anything; the syntax just grew, and common features were sometimes longer than rare ones: http://www.perl6.org/archive/doc/design/apo/A05.html (section "Poor Huffman Coding").

I haven't studied enough of the Git plumbing to know what's going on underneath, but I suspect that the same thing is going on, where features are added without regard to other ones already present (feel free to correct me on this)

I understand that Git is a fairly complex utility. But you can accomplish a lot just memorizing about 5 Git commands and what they do. Besides, if you decide to use an abstraction such as this one without understanding the plumbing, what do you do when 'git sync' fails due to conflicts?

The purpose of Legit is to save time for developers that know Git well. It is not intended to be a shortcut for newcomers.

When a merge fails, it gets you out of the merge conflict state and prints a nice message about what to do next.

The same thing I do when my hardware misbehaves and I don't understand how it works and why it failed.


Just kidding. Argument by Reuction Ad Absudum is fun, but in this case, you make a good point. There is a difference between a utility designed to make someting you understand easy and a utility designed to put an easy-to-understand facade in front of something you don't understand.

I think the only two commands from this I like are `git sprout newbranch` and `git unpublish branch`. But only because I think `git checkout -b newbranch` and `git push origin :branch` are stupid syntaxes for doing what they do.

I agree regarding `git push origin :branch`.

From the git man pages [0]

> git push origin master:refs/heads/experimental Create the branch experimental in the origin repository by copying the current master branch. This form is only needed to create a new branch or tag in the remote repository when the local name and the remote name are different; otherwise, the ref name on its own will work.

So, a direct substitution of `git push origin :experimental` says

    Create the branch :experimental in the origin repository by copying no branch
I definitely think that could use another layer of abstraction.

[0]: http://linux.die.net/man/1/git-push

git push origin refa:refb

  PUT a branch refb with the commit-ish refa
git push origin abc123:refb

  PUT a branch refb with the commit-ish abc123
git push origin :refa

  PUT a branch refa with the commit-ish null

Much more concise explanation, thanks!

Oh dear. Please, no. Just, no.

git's user interface is terrible and very counter-intuitive, but if you want to work in a team or, more to the point, be productive and leverage what git has to offer, do take the time to learn its native user interface.

Related article:


That's silly. As developers we constantly try to make better interfaces for our users. When it comes to our own tools we supposed to put up with difficult interfaces because that's the way it is?

Engineers seem to treat mastering the command line and complex tools as a badge of honour, and as a way of differentiating themselves from the noobs. If there is really an easier way then is that really a bad thing?

> That's silly. As developers we constantly try to make better interfaces for our users. When it comes to our own tools we supposed to put up with difficult interfaces because that's the way it is?

We're not talking about a different interface here but a new terminology.

It's a bit like saying that you think English is too hard so you'll be communicating in Spanish from now on. This is not a realistic decision in a world where you need to work with a lot of people who all communicate in English.

Extending your vocabulary is nothing like learning a new language. A text based interface is improved by choosing words and symbols that better represent a command with relative brevity and simplicity.

The concensus seems to be that commonly used complex actions in git have a less than intuitive structure and syntax. I think it would probably benefit from the introduction of new terminology.

Your analogy is wrong "terminology" and "language" encompass a radically different scope.

The actual analogy you should have used is: English is too hard, so we will use simplified, task specific terminology (or better yet, pictographs) to ensure task specific communication in a multilingual environment.

When you are working in a multi lingual environment that has built in restrictions and a short list of common terminology (like at an assembly plant, or github commands) it is much easier/faster/simpler for a korean and brazilian (lets just say) to communicate using a short list of common, simplified, task specific english terms like "bathroom, please", "dangerous", "stop production", "broken", "connect here", "lift here", "this side up", that is oriented around the things they actually do at their job.

Hell, give this thing a GUI that is just a bunch of easy to recognize icons and you will have something approaching the real world solutions that are commonly recognized as best/safest practice.

The purpose of Legit is to save time for developers that know Git well. It is not intended to be a shortcut for newcomers.

I hope the developer thought very carefully about how to handle doing operations starting from unusual states.

"# Switches to branch. Stashes and restores unstaged changes."

I guess I can't think of anything in particular, but I feel like something unexpected could go wrong here.

(I didn't know you could pop a the last stash that was made on a given branch?)

It seems like the use case he's optimizing for here is if you're accidentally on the wrong branch, and need to move your working changes over to the correct branch.

Personally, I almost always use stash if I'm not quite ready to commit, but need to quickly fix a bug that takes precedence over whatever I'm currently working on. I stash what I'm doing, fix it, and them come back. Some of these operations seem at odds with my workflow.

I've used that workflow too. What disturbs me about the `git switch` proposed here is the unstashing. I think the intended optimization is more general: when you're trying to switch to another branch for any reason but git doesn't let you because of unsaved changes. But your use case of being on the wrong branch seems like the actual optimization for a fairly (at least for me) uncommon workflow. More frequently I, like you, stash and switch, then possibly do something (or not) like immediate bug-fixing, then switch back and unstash only then.

There's nothing stopping you from using regular `git checkout` in that case :)

I'm in full agreement with the other comments I'm seeing. These kind of additional tack-ons are somewhat pernicious to actual team-based version control, because it promotes abstracting more of the core functionality of Git outside of the user's control. This causes breakdowns in mutual understanding and the ability to communicate at the worst possible time -- when people are trying to figure out why there are weird changes to production code, or what happened to the changes they made. As a technical lead, I would actually tell a developer using this to cut it out and learn the real commands so they know what they're doing.

I wrote something vaguely similar a while back, I imagined it would be useful in a hackathon context for people who had never used git before. The biggest problem was that it doesn't help people understand git, whereas all of the regular git commands fundamentally make sense if you think about the way it's implemented, and also lead you toward and understanding of git.

My version was called jerk--it is a little meaner than git, and supports operations like "undo".


this is brilliant :D

If you know what these commands are doing under the covers, these commands are a true time saver. If you don't know what these commands are doing, they're basically "magic" and in the hands of inexperienced developers could be harmful to their education on Git.

I completely agree. I hope to add a `verbose` mode that prints every git command that is being run under the covers.

It could be a good teaching tool perhaps?

Actually, a 'debug' or 'dry-run' mode that simply prints out the git commands without running them would be useful for all kinds of users. Newbies can learn from it and pros can make sure that the commands are going to do what they expect it to. With git, I know what each command does but my concern with legit (and similar) is that the higher level commands might not do exactly what I think based on their name/description.

I really like this idea. I consult Stack Overflow or the git man pages frequently enough to make it annoying, but infrequently enough to have the appropriate magic incantations become instinct.

However, if I am going to distance myself from the bare metal of git, why not go all the way and use something like GitHub for Mac? That seems like a true "Git for humans". I love working from the command line as much as possible though, so I will watch this closely to see if it becomes widely adopted.

I like the idea here, but see one significant problem that will prevent me from using these aliases. The git publish alias doesn't take a branch name, so if you have multiple remotes for the repository it will just publish to one of them. Which one? Well, the code in legit/scm.py reads

return repo.git.execute([git, 'push', repo.remotes[0].name, branch])

so it just pushes to whichever remote is first in its array. What if I want to publish to a second remote?

Then use `git push second-remote foo`. There's nothing stopping you from using the existing commands.

It's complementary.

What happens if flying green monkeys attack just before you hit "Enter"... I contend most people only use a single remote.

It's probably better to just write one's own wrapper for git that best fits you/your company's workflow, especially if it's for your company, since you can better justify the time spent writing the wrapper code. As a point of reference, the company I work at (five devs total) is moving off cvs(!!!) to git, but writing a wrapper tool to git to create branches and set them up in the manner we need for our product.

git-flow is awesome. I use it every day.

This isn't so much of a branching model tool, but a tool that allows you to switch branches and interact with remotes very easily.

When you switch branches with Legit, any pending changes you have made are stashed automatically. When you switch back, they are unstashed. This saves me a lot of typing.

If you're following Vincent's branching model, switching from `feature/x` to `develop` happens quite a bit. So, they compliment each other well.

Seems like a cool idea, but would be way (I've never even heard of the pip command before) better if it could be installed in one command. See http://betterthangrep.com/, https://github.com/defunkt/gist or http://beginrescueend.com/.

Pip is a replacement for easy_install


Pip compared to easy_install:


pip is used to install Python packages.

Is this just syntactic sugar?

I'd have to agree. Git is very Unix - simple commands do one simple thing - it doesn't need complicating by opaque commands that do lots of things at once.

But Git commands map to what is going on in the code, which isn't necessary. I think an effort to make a true CLI for git should be encouraged. For example:

  git push
Pushes everything, in every branch.

  git pull
Whoops, won't let me do that without providing a branch.

There are discussions about changing the push default behavior.


Erm... push behaviour can be changed using config and will be changed in the next release to only push the current branch.

My git pull pulls the current branch...

> Erm... push behaviour can be changed using config

Right, and isn't that what legit is providing here? Sane defaults. I'm in favor.

The point is, the best way to improve suboptimal behavior in an open source project is to engage with the project and advocate changing the behavior. If there is truly a defect, or a behavior that so needlessly violates the principle of least surprise, then fix it at the project level.

Completely agree... I don't understand changing an existing CLI... why not suggest improvements to the actual project?

The only way this could be justified is as a concept build to pass back to the community.

Looks like a set of aliases. Relevant source is here


I hope so. Lack of syntax sugar is "just" what forces me to stick with mercurial + hg-git.

I take offense to the "just" and the "sugar".

You making sound like something bad for your health.

An alternative syntax can make:

1) usage simpler 2) multiple step processes turn to one step 3) commands easier to remember 4) less error prone

(or the opposite, depending on the specifics of the new syntax).

So, no, this is not "just syntactic sugar" this is "new syntax", that is: an alternative command line user interface.

The phrasing is intentional - a new syntax needs to be substantially better (as opposed to slightly better) than the old one to justify adding an additional standard.

Incremental and clarifying progress is always beneficial.

I am on the fence as to whether this is clarifying or not. Git's problem is not just that the command structure is... esoteric, it's that once you're off the golden path, finding your way back onto the path is extraordinarily difficult.

I am unclear as to what extent legit mitigates the second (thornier) problem.

Incremental and clarifying progress is always beneficial.

Only if everyone increments with it. If you have half a team using one set of terminology and half the other then it's going to end in an unholy mess.

Looks like it's just aliases. You might as well just use 'git alias'. There's no need for a new universal set of commands - it defeats the idea of configuring your very own Git.

I disagree. A lingua franca is important. If these are indeed common operations, then it's important that everyone talking about, say, `git sprout` means exactly the same thing.

"A lingua franca is important"

Exactly! And that lingua franca already exists. This is only useful if you would like a new syntax for personal use and you're too lazy to or don't want to use 'git alias'.

That argument says that we should never codify abstractions built on top of pre-existing lower-level components. Not sure I can agree with that.

>Exactly! And that lingua franca already exists. This is only useful if you would like a new syntax for personal use and you're too lazy to or don't want to use 'git alias'.

Well, the lingua franca that "already exists" is the standard git syntax.

This syntax pains some people. Now, to alleviate the pain they could either use each their own aliases OR they could share a common new "lingua franca" of aliases.

That's what this project does.

In other words, what you're saying is:

1) a lingua franca is important 2) so use standard git, which is a lingua franca, or have your own personal aliases.

This just doesn't follow.

If a lingua franca is important, then, FOR THE SUBSET OF PEOPLE THAT DON'T LIKE GIT SYNTAX, to have a common alias lingua franca is also important.

It doesn't matter that it's less of a "lingua franca" that standard git-alese, because it is still a lingua franca for that subset, and solves the problem they have with the more established lingua franca.

The problem with "porcelain" like this is that it's invariably opinionated, and sometimes I'll want to do things that the simple, opinionated workflow doesn't allow for. And you still need to learn how Git works, which isn't really that difficult for someone who already understands the concept of a linked list, i.e. any competent programmer.

From the site:

>Legit is a complimentary command-line interface for Git

I do realize it's free, but I think you mean complementary.

Whoops, fixed :)

I personally like git-flow, but this is just a symptom of git inconsistencies, like git branch and git checkout both work with branches. I think it would be very useful to have higher level git that would be adopted as standard interface.

For those, like me, that had never heard of pip:


For those who don't want to click:

pip: because creating a replacement for easy_install was simpler than creating easy_uninstall.

More stuff to remember, I'd rather remember the original commands to be honest.

Le Git - git for redditors.

I think he ment to write "Git for farmers"


First of all, these verbs are only marginally more intuitive than the existing git verbs. Git when it is confusing, is confusing because of the underlying interactions and concepts, not because "push" is too bewildering compared to "sync".

Second, is the global "tower of babel" noise that widespread adoption of this alternate vocabulary will cause less than the slight local reduction in noise from legit?

No. Basically, this isn't a good idea and I really really hope no one adopts this.

so this is basically a bunch of aliases?

I'll stick with the Git GUI.

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