Legit. Git for humans
git-legit.org
git-legit.org
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.
the git vs EasyGit diff basically summarizes what I'd change about git.
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 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...
But it doesn't lead to an obvious, consistent command syntax, and that was the point.
Better example is tar vs cp, where you go
cp files you want to copy destination/
and tar destination.tar files you want to archive
And yes, I would say that's inconsistent.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 :)
It's surprisingly hard to unstage a file.
Is there a case when it's not a simple git reset my-file away? 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.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.
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.
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
or: git push ~pyre/work/repo staging:pillmv-staging
to push to a location that you don't have specifically defined as a remote.E.g.
% 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> 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.'
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.
git tag
Lists tags; does not create new tag git stash
Stashes current changes; creates new stashList tags/stashes:
git stash list
git tag [-l]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
Beyond that, git reset won't get you anywhere that you can't get back to after consulting the reflog
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: "????"
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.
http://people.gnome.org/~newren/eg/ https://github.com/blog/333-easy-git
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.
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.
complement.
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.
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.
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.
Just learn regular Git rather than re-inventing the language.
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?
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.
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.
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.
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?
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.
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.
The mathematical principles underneath are good, but the standard regex syntax is arcane and values brevity over readability, modifiability, etc.
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)
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.
:-)
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.
When a merge fails, it gets you out of the merge conflict state and prints a nice message about what to do next.
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. 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 nullgit'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:
http://beust.com/weblog/2010/04/06/git-for-the-nervous-devel...
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?
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.
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.
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.
"# 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?)
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.
My version was called jerk--it is a little meaner than git, and supports operations like "undo".
It could be a good teaching tool perhaps?
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.
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?
It's complementary.
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.
http://pypi.python.org/pypi/pip
Pip compared to easy_install:
https://github.com/kennethreitz/legit/blob/develop/legit/cli...
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.
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.
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.
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.
git push
Pushes everything, in every branch. git pull
Whoops, won't let me do that without providing a branch.My git pull pulls the current branch...
Right, and isn't that what legit is providing here? Sane defaults. I'm in favor.
The only way this could be justified is as a concept build to pass back to the community.
>Legit is a complimentary command-line interface for Git
I do realize it's free, but I think you mean complementary.
pip: because creating a replacement for easy_install was simpler than creating easy_uninstall.
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.