The underlying technology of git is great, but the UX is terrible. The commands are all named wrong. "To create a branch, use git branch, but that doesn't check it out. If you want to create it and check it out at the same time use "git checkout -b", not "git branch --checkout" which would be 1000x more logical (and then there could be an option to make that the default behaviour)
Resisting GUI's is not a good idea. The trick to learning is to always have `gitk --all` or a similar viewer open in another window.
Also instead of `git add` / `git commmit`, use `git gui`, but for most other things stick to the CLI.
Having said that use a GUI, github desktop is terrible. It tries to make things easier and as a result takes you away from git's standard terminology, so it's impossible to understand what it does.
Something I found teaching other people is it helps a lot if you haven't learnt SVN before.
I don't think memorizing commands is really the problem. Learning just 8 git commands (clone, pull, checkout, checkout -b, commit, push, merge, rebase) will cover like 99% of situations average dev will ever encounter. And when you need something more exotic you usually can google it, usually in under 5 mins.
The problem, at least for me, was the complexity of the model which makes the whole thing super scary when you've just started using it. That's where GUI tools come useful, as people are generally less scared of GUI tools - they make you feel there's less of chance of making a mistake because you put the trust in the tool to stop them doing something obviously stupid. However IME that trust is not really deserved as most of the GUI tools will just as happily let you mess up your repository...
You forgot log, cherry, stash, blame, which are also daily use commands. You also have to learn a lot of concepts to even understand the help and error messages for these commands - the worktree, the index, the stash, HEAD, ours vs theirs, conflicts, remotes, tracking branches, when it is safe to push -F, etc. Depending on the project you joined, you may also have to immediately learn about git LFS, submodules, squashing, fast-forwards, tags.
You have to understand a lot of things before you can somewhat comfortably use git, much more than something like P4.
The problem is not the 99% of situations that you can memorize, but the 1% of times when you realize you have made a mistake and strayed from your beaten path into the dark scary unknown Git woods where monsters with detached HEADs may be lurking behind every tree, and you have to ask a coworker or StackOverflow to rescue you...
Git might not be easy, but it's not complex, it's simple. There are basically only four concepts: blobs, trees, commits, and refs. Which systems (not just version control - systems in general) are simpler?
I think more than one thing can be a problem. The CLI is confusing and the model is complicated. This means people can get themselves into weird, hard-to-debug situations. Or end up copy-pasting incantations in hopes of fixing problems, but instead might lose their work.
Part of it is feedback to me. The timeline view in most Git Apps makes it super clear to see where you are and where you can go. Starting out in Git with an established repo is like driving at night without headlights.
Even though naming the commands might be arbitrary choices, they can be practiced upon. One doesn't always have to fall in the semantic trap.
The main problem that I see with using git is that when you are part of a team, what kind of release and branching strategy should you use.
It's comparatively easy with one person team but becomes complicated with a team and even more if it's an open source project and now you have individual devs contributing their changes.
When I first started writing software I would often rewrite third party libraries I didn’t understand to reduce complexity.
After growing up and becoming wiser I came to understand I did this all because I didn’t invest the time to learn how these complex things worked. It also made me feel smart to write more code. Big mistake.
I can’t help but think a little bit of this pattern rears it’s head as the motivation for things like git GUIs.
There will be a maintenance burden and no matter how careful you are there will be bugs.
I write scripts for complex but infrequently used operations and drop them in ~/bin
I disagree. In my personal experience, learning git took a lot of trial and error, but now whatever terminal I sit down in front of, I know exactly which commands I have to run to do what I want in git. When using a GUI, it's fine for the easy/common stuff, but if I want to do something more complex I have to figure out how to dig through the options provided by the tool to get the result I want.
> learning git took a lot of trial and error, but now whatever terminal I sit down in front of
This insight why git, like other tools, is stupidely designed.
The "wrong" defaults and UX is the DEFAULT, and each USER must learn it.
Meaning:
UX * N Users = Wasted time and money
---
If I present you a screenshoot of a (real!) business apps with mis-aligned buttons, some put in weird places that mean different things that them are supposing by their labels, that use non-standard interactions that mix different UI paradigms, with rare color combinations (aka: vomit palette) , all in a SINGLE window (!), you think the solution is resist a better interface? Why we mock "regular" users or their enterprise providers, but somehow can't with ourselves?
I don't know why so many developers live in constant Stockholm syndrome and like it, and resist any suggestion to improve.
When anyone ask me about the tools I use (specially asked when somebody look at me using the terminal), if I liked, i say "No, this is the bad and ancient way, but we are here, stuck on this.."
Agree with you. A GUI is fine (and a good thing) as long as it is just for convenience and discoverability, and it doesn't abstract git away, hide its power or try to impose its own workflow.
IMHO, a good git GUI would show exactly what commands are being run (so it is useful as a learning tool) and their result and allow it being used along side the cli.
I use magit extensively and it has all these properties.
I think viewers like gitk or tig, or more powerful tools like magit/sourcetree/etc. when used purely to see your repo's history, are not only acceptable but are the quickest and most intuitive way of understanding what's going on. I'd hate to be restricted to `git show --oneline --abbrev-commit` or similar commands that don't show branches and merges.
The biggest hurdle I had to learning Git, if truth be told, was my own aversion to doing anything that wasn't easy. It seemed difficult, so I dug my heels in and say "No! I don't wanna! It seems like friction and that's too hard."
The fact is, once I got over myself and sucked it up and got my head around it, it really only took 2 days of effort to grok what I was doing and now it's easy.
So biggest advice I can offer is this: Get over it and get on with it. It seems like a pain in the ass now, trust me I know, but you'll thank yourself for making the effort in the long run.
We have no choice but to "get over it and get on with it". But it DID NOT have to be that way, and that's what makes many people keep their resentment. It's like a kind of "hazing" experience.
Thankfully there are tools that make it less horrible. Git Tower and Visual Studio integration come to mind as examples.
It's sad, however, that there's not been an overhaul of the git commandline into something coherent and usable.
For recent versions of git I'd suggest using "git switch" and "git restore" instead of git checkout.
It avoids much of the confusion from the checkout command, which does very different things depending on what flags you pass it. That said, this is only one git command. The rest still has plenty of room for confusion.
> The underlying technology of git is great, but the UX is terrible.
I think it really comes down to a difference in philosophy in terms of learning how to use tools. In the past, one had to read the documentation to figure out how to use a tool. So, for instance, running git --help or git branch --help would give the information needed.
Now having a what's considered an intuitive interface is expected, which is why many people have problems using tools where the documentation is there, but people don't want to take the time to read it.
I get what you are saying, and this makes sense, if you are in a situation where the problem your tool solves is so special and the target audience of your tool so involved that it makes sense to do things differently than the rest of the world.
This is rarely the case. Sometimes at the end you get nothing but a wet handshake. Think about vim: it is cryptic, does everything different than everything else out there , but it gives you something in return.
If you make your tool less inutive, but give users nothing in return, you are doing it wrong. If the interface of your tool does it one way in this corner and another way in that corner — so if you are inconsistent without good reason — you are doing it wrong.
Interfaces are about clear communication. Interfaces are the difference between a rugged 50k$ Arri Alexa cinema camera and a 200$ camcorder: the more Alexa has physical buttons and knobs for important things precisely in the locations where they should be, precisely behaving in the way they are expected. The cheap camcorder has buttons, encoders and levers sprinkled over it seemingly random.
The interface of a tool is good when it can be used intuitively even under stress, in bad weather and on drugs. This is ehat we all should aim for imo: tools that are more powerful/expressive AND more intuitive at the same time.
I like reading manuals, but not for things that could have been totally obvious if somebody spent a split second thinking about how to communicate it clearly.
It's not just the UX. It's the concepts the user has to understand in order to use git (without shooting their feet off or consulting a guru frequently).
If you use UX purely from the concept of User Experience, then failing to understanding the concept of something is a failure of UX.
That said, sometimes when you are frustrated by having to add special cases to your code, it's not your fault, it's because you're modelling a badly designed system in the first place.
This clearly isn't a popular opinion, but I may as well add it here: I like git. It's not that bad and not that hard to use. Occasionally I have to look up how to do something, usually involving git-filter-branch. But that's no surprise, because what I'm trying to do is usually inherently complex. I don't think a different interface would solve that. For most other stuff, git is simple and easy to use. It was a bit slow to learn, but most really good tools are (e.g. vim).
I think that's unfair because I don't see that git even has a UI - it's designed to be a command-line API. The thousands of terrible GUIs out there are so bad that using the command line directly is still the best UI. (I think GitHub has done a great job managing remote repos - I am only talking about local tools.)
I don't think Git has a "terrible UX". It really is no less worse or better than any random CLI program.
But yeah, I fear people have issues with Git because unfortunately they reflect upon their experiences with other SCMs (like Clearcase, SVN, RCS/CVS, whatever) and think the same terminology and concepts apply in Git and then it goes wrong.
Git is not really rocket science to use. People who find Git difficult or nonsensical should spend 4+4 hours of their weekend playing with Git while reading Pro Git. It's available for free at https://git-scm.com/book/en/v2.
Specifically, read chapters 2, 3, 5, and parts of 7.
You should intentionally skip chapter 10, more than likely you don't need it.
Keep Pro Git handy and come back when you've a specific need.
checkout -b seems more logical to me, but not even close to 1000x more logical. Whether it should go on branch or checkout is just an opinion. You're blowing some tiny disagreement up to ridiculous levels.
I actually dislike Git profusely but these arguments are very, very poor. git checkout --branch vs git branch --chekout ? Depending on how the wind blows I could see myself leaning on one or the other. WHO CARES? This is not even a paper-cut level of annoyance.
Kraken is the first UI that I've found that makes editing commit messages on previous commits easy. I spend an inordinate amount of time moving hunks between commits/etc in order to present a "clean" git log for a couple opensource projects i work on that have OCD maintainers.
Avoiding the rebase/edit/ammend/etc cycle is a huge time saver. What I really want it to do is be able to select a random hunk and move it as well...
I was on the GK team a few years ago, so I'm obviously biased, but I believe that GK—specifically the design of graph[0]—helped me a lot to level up my git-fu.
[0] which was created before my time at Axosoft, so I'm not that biased :-P
Within our lifetimes, an interaction most users have with a computer could be just thinking about something to cause an action. I don't want to have to see a GUI in my brain to do that. Similarly, not everyone likes having to use what is traditionally called a GUI.
For git, I prefer the CLI, though I use some helpers for completion, I have some scripts I wrote to show remote and local branches with their authors in different states of merge, etc. My guess is that in your GUI, you don't have that level of customization, and probably didn't even think it was an option. That's the problem with GUIs for me.
The whole point of the UI is so that your workflow is simplified without having to understand the exact inner workings of it all.
GHDesktop’s simplicity means that most of time I don’t have to call 4 commands to just check out a new repository or PR because one click runs all those 4 commands and more.
As simple as it is, lately I rarely have to use the CLI (which however I still use because I rebase and fixup)
The fact that “takes you away from the terminology” sounds like people complaining that Windows 95 users don’t know what MKDIR means: That’s the whole point of UIs.
I wish it wasn't coupled so tightly to emacs but magit is a phenomenal gui for git even for the more advanced use cases. if you know vim then spacemacs wraps it up in a more palatable package.
I've tried GUI interfaces to git before and I just haven't been satisfied by any of them. They seem to work right until I need to do something out of the norm. I did find git a huge PITA when getting started though but now that I have some muscle memory, I won't be trying anything new any time soon.
For Git clients in particular, there's the issue of GUI applications that think their mostly ad hoc, incomplete configuration should prevail over standard Git configuration (e.g. GitAhead is unable to use authentication tokens on Windows) or that their "opinionated" behaviour is good for everyone (e.g. try to modify a tag with SourceTree).
I've used git for ten years, at half a dozen organizations (I'm a consultant/contractor). I have accepted that it's what we use now, so I use it. But...
Git is the bad boyfriend of the developer community. If anything bad happens it was your fault. If you ask it to do something and it does something else, it was your fault, and also you are stupid. If you ever make a mistake, you will be punished for it with a long drawn out cycle of embarrassment. No matter what happens, it was not git's fault, it was your fault.
Good software is not like that. Good software is the opposite of all of that. Git is the industry standard, and I have just accepted that we aren't going to get anything better, but whereas it might make sense for the Linux kernel dev community, it is not good software, and I suspect that it's not just the UI that's the problem.
Lots of non-devs also have the problem of wanting to have multiple people edit the same document, track changes, and occasionally merge them. I would never recommend that they use git, and I see no evidence that it is ever spreading beyond the dev community in any significant way. There's a good reason for that.
Reading all of these threads, I think the conclusion is: we still haven't figured out how to do revision control in an intuitive way, because it is highly nonlinear and our brains just don't work that way. There isn't a clear vocabulary for intricacies of revision control, yet. And if you can't name something clearly, you can't explain it clearly.
The author's idea of putting an abstraction on top of git is the way to go. As an analogy, Git is a great toolbox, but sometimes you need a plumber. I like how apt and apt-get came into being on Ubuntu.
The comments about the logical inconsistencies in Gits command line are a clue.
When is the last time you wrote a CLI utility and listed all of the commands, subcommands, and options to make sure they all had a consistent look and feel? Most single-author tools do not do this. It is a consequence of developing in a vacuum. Team-based development allows other eyes to look at it and say "why is checkout used during branch in a different way then branches are checked out?". Git came from, essentially, one person. That's part of it.
But that is also a legacy of Unix/BSD. Consider `du` and `find`. Both have an option for max depth, but is it --max-depth, -maxdepth, --maxdepth, -d, or -m (or even -L for `tree`). There is a lack of consistency that is a rite of passive for Unix/BSD acolytes that even Gnu didn't fix... C'est la vie? Or maybe a /bin rewrite? bahahahaa who am I kidding.
There's no question Git is a powerful tool, it just needs to evolve and gain some consistency. And I think the answer is a higher level abstraction. And for the love of Benji, NOT a GUI.
> When is the last time you wrote a CLI utility and listed all of the commands, subcommands, and options to make sure they all had a consistent look and feel? Most single-author tools do not do this. It is a consequence of developing in a vacuum. Team-based development allows other eyes to look at it and say "why is checkout used during branch in a different way then branches are checked out?". Git came from, essentially, one person. That's part of it.
I think what's interesting is that, in the space of programming language development, languages that tend to have a more consistent feel across the language (such as Clojure, Python to some extent) tend to have BDFLs and came from a single person.
> If you ask it to do something and it does something else, it was your fault, and also you are stupid. If you ever make a mistake, you will be punished for it with a long drawn out cycle of embarrassment. No matter what happens, it was not git's fault, it was your fault.
Ready to be downvoted into oblivion for this, but: This is how a lot of the Linux/FOSS community is so it makes sense that Git is too, sadly.
Things have gotten a lot better with the attitude these days, but you know it's bad when StackOverflow needs to issue guidelines on being polite and how to answer questions without being rude/condescending.
What do you recommend in these cases? People in non-technical fields often ask me about collaborative software, "like google docs, but for non text files". My mind goes straight to VCS, but git is too hard to get them quickly up and running.
I tried SVN one time, which is a little simpler, but still didn't catch on with the person I was showing it to.
that would also be perceived as your fault. And yet, command shells are pretty good software.
As for non-devs editing the same document - unless that document is text (which typically it isn't for non-devs), I would probably not use git on them either.
You can't just say this without providing an example of what you think is good software, as, after all, good and bad are subjective and not agreed upon by all people for all things, as evidenced in this thread.
This is the root of the author's issue. As another commented, git is born in a world where computers are mostly offline, people are highly technical, and will spend a lot of time manually crafting the messages they will send to the numerous collaborators. It is an alone-first software. What the author wants (and exactly what I want as well: https://news.ycombinator.com/item?id=25002318) is the complete opposite: a system that knows it's connected to other people, where changes are instantly propagated and easily visible, where the differentiator between "branches" is not "what computer does it reside on" but "who did it". That's the model behind GitHub, after all.
git is complex because it's working with a very complicated model that is not in line with what most people expect today. As I said in my other comment it seems that fossil works with that flow, but I haven't tried it. However what is sure is that it doesn't make sense to ask git to become what it fundamentally is not.
EDIT: There might be a solution with wrappers. When you look at git-annex assistant (https://git-annex.branchable.com/assistant/) you can see that the right amount of abstraction can provide something closer to what we expect... but at this point it's not git anymore, so we might as well start from scratch.
>Oh, I just pushed a change. I really didn’t wanna push that, so how do I undo it?
Is a Github problem, not a git problem. You might as well ask how to unsend an email. If you don't know what git push means, you shouldn't be using it and are playing with intellectual property fire.
The conflation of Github with git is responsible for a lot of confusion. Having Github be your first interaction with git is a disaster.
Regardless, there's no shortage of blog posts complaining about git being hard. But there is a shortage of effective, popular competitors. I think that, actually, many-chefs many-branch differential version control is just a hard problem and creating a simple model for it is much harder than complaining about git.
I'm unable to fathom the notion that if a computer doesn't work the way people want, the answer is for people to adapt to the computer. The whole point of computers is to do things for people.
With physical messages, unsending has at least partial support. Before the mailman picks up from my porch, I can grab a sent message any time. If you FedEx the envelope, you can cancel before delivery. With a university's mail system, you can get the receiving department's admin to return something even later in the chain. And of course, you can always tell a recipient, "Hey, I sent you the wrong box, just send that back."
The reason email doesn't support unsending is not some essential property of messaging. It's just that at the time our email protocol was defined, both our hardware and software was pretty primitive, so we locked in a very primitive model of messaging. But note that more modern systems, like Slack and Facebook Messenger, happily let you unsend things. And consequently, they're effectively replacing email for most users.
I don't see what it's got to do with github. I had the same need, and the same confusion solving it, before I had ever used github, when I used a locally hosted git server of some kind for my team.
Do you mean it's a problem only if you are "git push'ing" to a remote shared by those working on a software project?
OK, maybe. Even before github, most projects I knew of using git used that method. You can suggest nobody should, and try to educate people in a completely distributed workflow if you want, I suppose. That's not about github really.
Right, it's also because github guides people into a history-only flow instead of rebase / force-push. Casual github users know they should follow the tree with pull and don't know what fetch is.
With history if you make a vcs mistake, or realize iteratively after pushing that corrections are needed, your worthless threshing around trying to fix it becomes part of your project log forever, instead of just pushing the corrected tree with just the one corrected patch.
Mercurial has solved this quite elegantly. The Evolve extension is basically standard functionality and all changesets (commits) have a state: secret, draft, public. You can share the changesets and you can "prune" them, which basically tells the world that if they have a changeset with that hash to delete it.
> If you don't know what git push means, you shouldn't be using it and are playing with intellectual property fire.
Whether you realize it or not, that's gatekeeping. The point of UX is to remove artificial gates. When people apologize for the gates instead of fixing them, well... That's tantamount to threatening people's livelihood. It's a lot easier to do that when you don't think of it that way, and it probably shouldn't be easy. "I understand it, you shouldn't work here if you don't" is literally, "Fuck you, I got mine," with different words.
> about git being hard. But there is a shortage of effective, popular competitors
There is only so much oxygen in a room. There is not space for a million solutions to every problem, and once the Hype Train has left the station all you have left is to make the fiction true, or try to accelerate the Trough of Disillusionment so we can get on with fixing the problems instead of deflecting.
And I say this as the only person on a large team fit to do anything approaching surgery on screwed up git repositories. There is frequently a degree of turf protection via "he's a bastard, but he's our bastard". No, he's just a bastard. I don't claim any responsibility, I just have to interact with him.
Not just Github. Having any GUI be your first interaction with Git is a disaster. Right now the only way to learn Git is via book or man page, and command line. All the decent GUIs I have used assume you already know Git. They are great and powerful, but they don't help at all with the onboarding process. If you know of one, please share. I had to stop using GUIs completely and learn with Git command line. Then the GUIs made sense.
Rather than a problem with GitHub, I think it's more just a problem of dominance. Git was originally designed for a work environment where people weren't on the same network, or any network at all when making code edits. At the same time, everyone wanted a copy of the history that they could change themselves to mirror their work. So we needed a tool which could be distributed, not require a regular network connection, and still enable people to share changes and view the entire history of a project.
Git was primarily adopted because it solved those issues which were important ones at the time, people discovering git needed those tools and when discovering git would naturally come across and understand the trade-offs. IE: "I can't easily undo a change once it's on someone else's machine, instead I would need to issue a new change reverting it. But that's ok, because it means I can do as I like on my machine without screwing up the history for other people and only send a patch of specific changes when I'm ready."
The issue people now face is git has become so popular, because of those initial reasons, and we're dealing with a new set of problems which git never cared about.
"Project X is in a git repository, and I want to contribute a change".
This is a fundamentally different problem to the original problems git tried to solve. We're now in this weird space where most people using git are only using it because: it's what they already know, or the project they want to work on already uses git.
Requests like "I just pushed a change and didn't really want to" don't make much sense and don't matter much in the original use cases. Now many git projects use centralised hosting and a lot of people don't really care about git, just getting their work done, we now have this UX issue. The UX issue isn't a result of poor design or implementation in git, it's due to the motivations of users being fundamentally different now.
Sure you could argue that git should change or be easier, but then it would stop serving the original purpose. If people want a centralised source control with the ability to easily retract changes and have branches be the same across all nodes then really they just don't need what Git sets out to solve.
The issue is git is now dominant, and that forces people to use it even if they don't have the problems that git is really attempting to solve. That means they're stuck in a place of using a tool so they can collaborate, without getting any of the benefits of it. That's enough to drive anyone insane! It's like pushing a boat across land to get to another village when a boat is really to get to another continent, but no one makes cars because everyone's already boats.
We don't need "better" UX for git, we just need people to know about all the options, and part of that may include encouraging some people to choose more centralised options when it's a better fit for them.
My previous and current company use perforce but many people (often those who recently join) are decrying that perforce is less elegant than git, but, realistically and based on your own criteria it would be "better" for the connected case.
I'm personally a big fan of 'offline/local-first' being a thing, but I'm a sysadmin not a developer.
I use Perforce everyday since it aligns better to the needs of the games industry.
I have my problems with it, but once you understand it I find the workflow quite simple.
If you don't really need the decentralization I think it aligns quite well with how people expect version control to work. You make edits to your data, once you're done, you send them to the server to be shared with other people.
I’ve had to use perforce before and was not a fan. Granted, I didn’t have to use it full time and can’t claim to be an expert, but I hated the notion of locking files, change lists, yuck. All of it felt so clunky compared to git.
Never used it but I had to use ClearCase at work even though I was already proficient in git.
Ugh. The centralized model is better for companies, but ClearCase really makes its best to make your life miserable:
- You have to think twice before modifying a file, because the steps to be able to modify a file can take from 30 seconds (if you already created the activity) to a few minutes (if you have to create it)
- Activities are supposed to be like branches, summing up all the changes. But there is no way to see all changes in one go. It's click everywhere, waiting for the server to reply on each click.
- Because there is no way to display the branch content in any way other than envisioned by IBM, there is no way to discuss a changeset. No pull requests, no exchange, nothing.
- Horrible UI/UX all around. It's slow, it's unreadable, random bugs happen all the time where the only fix is to restart the service, .... and it's expensive.
I'm not advocating for a system that only works when online (although the fully integrated system of Google does sound good), just that it be architectured around a point of centralization. This is the way I'd like to use git:
- A branch created locally will be synhcronized and visible to everyone by default
- A branch that I manually tag as private won't, but it will still be saved on the server
- A branch that has a conflict between me and someone else will be marked locally in some way (maybe a second branch ?)
- Bonus: my working repo and staging area are also synhcronized to the server
At my current job, I had to create a command-line tool just to be able to checkout things from perforce. It is ridiculous how difficult the UX is for this. And companies are still paying for it!
Not just that, they seem to suggest Github created Git...
> the quality of the tech that is Git is a testament to GitHub being able to make it this far in the tech space
But in reality, Github makes Git more complex, because now you have to understand the concept of forks. Not only is there your local copy and an origin, there is a 3rd repository in play.
I think we're all still dancing around a blind spot, where we want eventual, Pareto Principle consistency (where a consensus is formed around 10% of edit histories, many others require only a consensus of 2, and the rest are backups that require a consensus of 1)
We're trying to assemble this from different pieces, without a clear idea if we can even get there from here, given all of the roadblocks Information and other Theories throw in the way.
I hope someday we meet in the middle with systems that can handle code and incidentally a bunch of other problem domains we also care about.
> a system that knows it's connected to other people, where changes are instantly propagated and easily visible
We have this already. It's called collaborative desktops over VNC ...
> the differentiator between "branches" is not "what computer does it reside on" but "who did it"
So you're into collaboration, but not on branches? I would have said branches related to specific units of functionality, streams of development or specific issues.
Definition of branches aside, this is the way old-style centralised VCS like CVS, Subversion actually work - and you can still use SVN if you want to ... or you can use git in that manner and never have to worry about it's more complex details.
The whole point of Git is that it addresses the specific problem that once you are disconnected you de facto have a branch. Once you push to remote its more like that ideal you're reaching for.
> at this point it's not git anymore, so we might as well start from scratch.
I'm sorry this is really quite hilarious. Go! Stop whinging and go do it!
I don't understand the negativity. I'm not saying that git is bad, or that git sucks. It is what it is, and not wat most of the people really want.
> We have this already. It's called collaborative desktops over VNC ...
We still want a revision control system, things like commits and all.
> So you're into collaboration, but not on branches? I would have said branches related to specific units of functionality, streams of development or specific issues.
Depends on the workflow. Many people have long-lived branches, introducing big features/refactorings. Many other prefer short-lived branches, where one branch typically is used by a single person. I still think branches should be focused on topics, but the topic (and thus the branch) must be the same on all computers, instead of having one version locally, another one that is mapped to it but potentially has different content on the server, and 1 different branch per other user. How many times have we had to "oh you pushed on your branch, I have to get it first"
> Definition of branches aside, this is the way old-style centralised VCS like CVS, Subversion actually work - and you can still use SVN if you want to ... or you can use git in that manner and never have to worry about it's more complex details.
Yep, that's the model: one place where people synchronize. The issue with those was not the centralization (look at GitHub), it was the lock mechanism. I can use git to replicate it, or I can use the folder.bak and folder.v1.final on a NAS method. It's not because it's possible that it's desirable
> I'm sorry this is really quite hilarious. Go! Stop whinging and go do it!
Ah, so it's not possible to criticize work until we have developed a complete alternative ?
While the above is tecnobabble, there /is/ a simple way to state what git is. It's an API to interact with a torsor.
We have files, which are inert objects and form a "file space". We have diffs. Diffs can "act" on a file to produce a new file or a conflict --- we call this as "applying a patch". Mathematicians would call it a "group(oid) action". Diffs are a groupoid because (1) there's an identity diff that does nothing, (2) diffs can be smashed together, (3) if the smashing of diffs succeeds, the operation of concatenation is associative, (4) all diffs are invertible. If we were to delete added lines and add the deleted lines, this inverts the diff.
Finally, we have a rooted DAG where each node is a diff, and the root is the empty diff. Git queries enable to manipulate paths in the DAG, which corresponds to smashing together diffs along a path to produce a file.
If one groks this, the rest of git is a pretty poor interface on top of this nice mathematical structure.
How is this any less technobabble? I looked up torsor on wikipedia. I learned nothing, except that "torsor" is a real word, and not just something you made up for a joke.
While this sounds all nice it actually fails to model Git as it is. Git is an object database and its objects are blobs, trees and commits not diffs, so your premise is based on a misconception.
While this is a wonderful explanation for a person already familiar with mathematical concepts such as groupoids, torsors, and directed acyclic graphs, I think that this explanation is really unfriendly for the layman/novice developer who's just trying to get their changes up on Github.
All is well until you need merges, which is where the confusion happens and minds are lost.
- You have a branch `master`.
- You have a branch `feature` which contains commit C, which conflicts with `master`.
- You merge `feature` into `master`, fixing conflicts.
- You log the commits of `master`.
* First is the merge commit, whose diff contains code added by commit C (including the conflict resolution).
* Next you see commit C, whose diff contains code added by commit C (obviously)
Wait, how can 2 commits in a row have a diff that modifies the code in the same way? Well, mind you, the diff of a commit doesn't correspond to the moment the patch of the commit was added to the current branch, it only corresponds to the moment it was added to its own branch.
Ah, so just a file space with a rooted DAG where each node is a diff with paths manipulable by queries where diffs can use a groupoid action to produce a new file or conflict, resulting in an API to interact with a torsor.
This is funny but I think it strikes at a real truth: what Git is trying to do is legitimately difficult. I can see where the author of the article is coming from and I agree that Git has a lot of commands and it's hard to pull it all together, especially if you are new. And I agree that these commands could be better organized and presented and I think that's something the project is actively trying to address.
But isn't the core idea of Git, everyone has their own repository and they share branches, kind of complicated and tricky? In my experience the developers I see having problems with Git are having trouble with the hard stuff, not the easy bits like committing and pushing a change.
Mercurial shows that it's possible to hide much of that complexity behind a user interface that only exposes as much of that complexity as necessary.
Git's--and Mercurial's--secret sauce is the directed acyclic graph of commits.
Everything else is window dressing. It's complicated if you're used to a linear sequence of commits, but it's not too hard once you grasp the tree structure.
All operations are operations that manipulate (or share) the DAG, so it now becomes a matter of mapping how you want to manipulate the DAG onto the command set the tool gives you.
Git's toolset was designed by a dozen madmen that didn't talk to each other, so it's a loosely connected set of tools with conflicting syntax and meaning. Mercurial's toolset was designed to be used, so if you know the right terminology, you can easily figure out what command to write. Want to commit something? It's probably hg commit. Want to rebase? It's probably hg rebase. Etc.
Git exposes unnecessary complexity. But it won the DVCS popularity contest, so we're stuck with it. I wish something else had won. Oh well...
git is a fast, content-addressable, decentralized and symmetrically ad hoc synchronizable, cryptographically verified filesystem, stored as a directed acyclic graph of tags, commits, trees and blobs, in that order, with SHA-1 pointers as edges, backed by a POSIX filesystem, with both a simple storage format and a space- and seek-efficient, compressed delta chained pack format.
I don't agree at all. Git is the simplest version control system I've ever used. The concept of merging, rebasing, cherry-picking, and resetting works so naturally that I'm basically going to expect this level of ease of use from any VCS I use going forward.
That being said, I know there are some who have trouble with Git. But IMO it isn't because Git is hard, but because they don't have to truly understand Git to use it. That's how easy it is.
>But IMO it isn't because Git is hard, but because they don't have to truly understand Git to use it. That's how easy it is.
A copy&paste of my previous comment:
Everybody's brain is different but I actually understand all of git's internals (the "plumbing") but it doesn't help me with the git CLI (the "porcelain").
Yes, I know that Git is a DAG (Directed Acyclic Graph), and that HEAD is a pointer, and the file format of BLOBs and SHAs, etc. If I were to implement a DVCS, I would inevitably end up reinventing many of the same technical architecture decisions that Linus came up with. But none of that insider knowledge really helps me remember git syntax if I haven't been using it in more than a month. Even though I grok git's mental model, I still can't answer the top-voted "git" questions on Stackoverflow without a cheat sheet: https://stackoverflow.com/questions/tagged/git?tab=Votes
The git UI and unintuitive syntax is just too hard for me to remember unless I use it every day.
Also to add.. the concept of "git index" as a staging area adds some complexity as well. Yes, there are good reasons for it (1) it lets one craft a specific subset instead of all changed files to commit and (2) it's a performance boost because a Big-O type O(n) loop runs faster when iterating through the staging index (small "n" of dozens) to detect changes instead of looping through the entire source code tree (large "n" of 10,000+ files in a big repo). But that flexibility adds an extra cognitive burden when a newbie just wants to save a "backup snapshot of the repo". For a newbie, the extra indirection layer of "staging index" seems superfluous and confusing. That's why some present an alternative porcelain to git that doesn't expose the staging concept: e.g. https://gitless.com/
(To clarify, I'm not recommending Gitless but just giving an example of why some felt motivated to simplify Git's porcelain.)
I fully agree that the default porcelain has poor UX for managing the staging area, but doesn’t a porcelain without it encourage overly large commits?
All sorts of workflows become substantially more difficult (if not impossible) with kitchen sink commits. Undoing a single-line change, for instance. I dislike large pull requests, let alone commits that introduce a half dozen different changes.
Sure, if you’re really disciplined you can produce small commits without staging, by committing as you go along, but you’re breaking flow every time you commit in this style.
I say all this because I would love a CLI that has half-way sane handling of (e.g.) restoring staged, deleted files; doesn’t conflate restoring files with switching branches; has consistency of flags between commands (such as commit vs stash message); etc., etc. I should try gitless ;)
> But that flexibility adds an extra cognitive burden when a newbie just wants to save a "backup snapshot of the repo".
Simple needs have simple answers.
git add .
git commit -am '2020-11-17'
Sure, you can ask "why are there two commands?", but this is not so much an issue of cognitive burden as of typing burden. If you only want one thing, you only have to know how to do one thing. If you don't want to know why the procedure does what it does, you don't have to.
This was surprising to me, and shows how different people's experiences of git can be. My workplace switched to git from an obsolete centralized VCS earlier this year, and I could easily answer these.
Something like this is probably where the line between those in this thread who agree that git is too hard, and those who think the detractors are just lazy and stupid, runs. Folks, people are more different than you expect!
> Even though I grok git's mental model, I still can't answer the top-voted "git" questions on Stackoverflow without a cheat sheet
This sounds like you just don't use or need those things much, which is fine if it works for you. Of the top 10, I can answer 9 of them without doing any research because I've used these commands a lot and they've become a part of my workflow. The one I'm missing? I've never renamed a git branch. If I needed to, I'd probably just do git branch --help or google it and figure it out in five seconds.
You don't need to commit every command of the program to memory. Just like anything else in tech, knowing how to find the knowledge you need is good enough.
For the questions, what's bad with quick help on SO? It's maybe less effective than reading the documentation that ships with git itself but for sure much more popular and less to read.
Git truly is a command-line utility, little known is that it ships with more than one gui in the base package out of the box. handling the staging area with git gui for example is straight forward unless you have more than 5000 unstaged files, then the gui informs you about it's limit and mass handling is far easier on the command-line anyway.
I feel the same way, I understand git pretty well but cannot for the life of me use the CLI. Fortunatly there are some pretty good GUI around, I personally use GitExtensions and find it suits my brain nicely. Its windows only though, not a problem for me since my work forces me to use Windows and I don't code at home but surely they are nice git GUI for Linux no ?
Totally agree on the "staging area". I've always thought that the staging area should only activate when you `git add` or otherwise add files to it. If there are no staged files, then git commit should act like git commit -A.
I'm not an idiot, but I don't fully understand git. I am coding for a living, and I use git every day. I probably could sit down for a couple of days and fully understand how git works, but I've never needed it, I understand how basic git operations work, and I stay away from commands that I don't understand. With GitHub desktop you don't need to open the command line for any standard operations, I only need to use the terminal for cherry picking.
The reason I want to stick to the basics is because of one interesting thing I've noticed: a lot of engineers sincerely believe that they are git experts when they are nowhere close. And until I locked down the GitHub repo with admin privileges, that was a dangerous thing. So I'm trying to work a system where no one in a team where not everyone is truly expert at git only uses the basic commandset from git.
One thing I can say again to emphasize - git maybe the simplest Vcs you've used, but it's not a simple tool, and its most definitely not intuitive for everyone. If it is for you, that's great, but maybe there's a lesson here about how not everyone's brains are wired the same.
I've definitely been the victim of my own git hubris.
Once, when leaving a job, I decided to copy all of my local WIP branches to the server.
I whipped out this fancy --mirror option I had just heard of:
git push --mirror $remote
Surprise! All branches on the remote repo got wiped. My local refs replaced the refs on the remote.
Somehow I found the right commits floating around in the git ether. I was able to recreate the branches, but I had to recreate their names by reading the commit log.
Did I mention this happened on my way out the door from a job? In retrospect, I shouldn't have panicked so much -- there were daily backups -- but the sheer terror I felt has made me read the man pages really closely to this day.
I'm not sure I follow your logic: why not take a few days to learn the fundamentals of git? I did that a few years back (and I'm not saying I read the source code, just learned about the base concepts from a few blogs and played around with some more advanced commands), and it has paid dividends _every single day for the last several years_. For example, I avoid tracking branches and have started using `git fetch`, `git merge --ff-only <remote>/<branch>`, `git reset --hard <remote>/<branch>` and `git push <remote> <branch>` to push and pull remote code. Even these slightly lower level commands will start to help you understand what's going on behind the scenes and take the mystery out of, say, rebase conflicts.
> I probably could sit down for a couple of days and fully understand how git works
This means it isn't hard. If you are capable of understanding algorithms of any complexity you should be able to learn how to use git (and how much of it) without treading on ground that is dangerous for you to use. All of this "it's too hard" rhetoric is infantilising or coddling people who frankly shouldn't be trusted to code anything of importance anyway. There's no shame in admitting your own limitations, but there is definitely shame in lowering the bar for others so much you are actively harming the industry.
That’s a similar approach to mine. I tend to learn enough about something to “get the job done.”
This is both good and bad. I get a lot done, but not always as efficiently as possible, and I do find myself realizing, down the road, that I didn’t need to do it that way.
But it’s entirely possible to get caught in “tool rabbitholes,” where the main goal becomes subservient to the infrastructure.
I remember dealing with folks that would spend three days, writing CLI tools that saved, maybe two hours, over the course of a year.
> I'm not an idiot, but I don't fully understand git. I am coding for a living, and I use git every day. I probably could sit down for a couple of days and fully understand how git works, but I've never needed it, I understand how basic git operations work, and I stay away from commands that I don't understand.
That's a great summary for the majority of Git users. I am still motivating people to spend the time to learn it "properly" if they're using Git daily.
First of all, it will make them more efficient. I've seen too many people literally redoing their changes, because a cherry-pick/rebase is "an operation they don't understand".
Secondly, they will be able to solve most issues when (not if) they occur. Sure, I am more than happy to help my colleagues solving their issues. From "why are those changes in my PR" to "our Jenkins job went rogue and now we've got hundreds of MB of data in our repository that we would like to remove". But the time of me explaining things the "learning by doing" style would be better spent actually learning Git.
Imagine SQL databases worked exactly like they do now under the hood, but instead of current SELECT/UPDATE/INSERT/DELETE they used like 15 different commands with at least 4 switches each.
So instead of SELECT you'd have FETCH, PULL, CHECKOUT, CLONE, READ, PEEK, and OBSERVE. And each of them could in some cases also modify or even delete the data depending on the switches.
Imagine there was no division between DML and DDL - you just have to remember which option switches change the schema in addition to doing some other things.
And then people would say "SQL is very simple, just learn relational algebra".
That's how I feel about git :)
With SQL I know for sure I can't break the database by doing a select. I know I can't change schema by doing a DML.
With git I'm pretty sure I can't break anything by doing git status, but other than that all bets are off.
SQL presents an static picture. It doesn't really provide a way for you to manage and integrate several different views of the world or provide a means to retrieve the history of all changes you have made throughout all of history.
In your list of shout commands I don't see anything that could be used for merging? I guess the "language" of git could be tweaked to make it more consistent, but otherwise the problems it is trying to solve are more complex than what could be dealt with in a SQL dialect.
Agreed - I started to use version control back with SCCS somewhen in the early nineties, and RCS, CVS, Subversion, ClearCase, some Microsoft horror with a name I can't recall, and a few others. My conclusion is exactly the same as yours: "Git is the simplest version control system I've ever used." And it also improved my overview over what happens and has happened in the past - I can jump back in for stuff I haven't touched for many years. So I now think of the older version control systems I used over the years as simple "snapshot backup" systems, not real version control.
(NB: I've never actively used Mercurial, other than because some projects use it, so I'm not comparing Git and Mercurial, or the other one or two systems with similarities.)
I don't get that either. There have been people here arguing that svn and mercurial were both easier to use than git.
But the moment I could import SVN to git I immediately switched to Git for everything. And Mercurial... I guess it's a matter of preference, but I personally never got the hang of it. And the fact that they had both SVN style continuous IDs AND hashes was deeply confusing to me.
The only thing I did find confusing in the beginning was a) the distinction between pull and fetch. b) getting used to the fact that I don't really care about continuous IDs (or hashes for the most part ) and think more about commits relative to where I currently am.
In addition to that things such as `git add -p` or `tig` are so much more convenient compared to other VCS CLIs. But even if CLI isn't what you want we're now a couple years beyond having beautiful third party Git GUIs
The underyling concepts are fine, the problem with git for me is the inconsistent command line interface. Stuff I'm doing less often than once a month I have to check in the manual every time. And it's nothing inherently hard - stuff like removing one change from staging or cleaning up local branch to be exactly like remote. The interface just feels like stuff is arbitrarily assigned to different commands :)
I click on the file and click on "unstage". I don't know why people insist on using the command line for their dvcs. Is it even possible to selectively unstage or reset only a part of a file without a GUI?
I've used a lot of different version control systems over my many years in the industry and git definitely isn't easy. The basics aren't hard but it's easy to get into a pickle if you need to delve slightly out of common patterns.
The git CLI tool isn't great either -- that's probably the hardest part of git.
Quite some years ago we switched from git to Mercurial and the amount of VSC mentoring and unfucking the "VCS guys" had do became almost zero. People seriously just got it. Some argued that is was because they had to learn with git, but... since then we've made the switch back to git for other reasons and we've back at wrangling with the tool again. I'd much much rather use Mercurial with Evolve extension - that is really good.
I’d be inclined to disagree. I found the learning curve to be quite steep. When you’re used to having a centralised VCS hosted for you it can seem a bit of a chore to take on all this extra responsibility. Once you’re on top of it though it’s great I wouldn’t use anything else.
> When you’re used to having a centralised VCS hosted for you
I think this is the crucial part. Git will come off as difficult and strange if you're used to using a centralized VCS, and expect Git to work like it. But that isn't really indicative of Git's own complexity, just its differentness.
I think there are many aspects of Git that are obscure/error-prone regardless of how well you understand its implementation.
For example, the concepts of "ours" and "theirs" when looking at changes depends on the current operation mode (rebase vs merge).
Merging is unsafe-by-default, because it auto-merges even if both branches have modifications to the same file, and there is no guarantee that the resulting file is correct.
There are numerous ways to collaborate on a git repo, with vastly different performance/usability implications, none of which is obvious when you start up (merging remote into local, rebasing local onto remote, squashing local commits; patches vs pushes).
Not to mention that, for teams that work with a centralized remote repo, the whole concept of local tracking branches adds mental overhead for nothing, and extra work every time you want to push a change to a remote branch. You have to first pull, even if your changes and the remote ones don't touch the same files. Which of course means that, if you had a dirty worktree, you actually need to run 3 commands - one to stash your changes, one to pull, the actual push, and now an unstash.
Git is I think objectively more complicated any other popular VCS, simply due to the fact it has much more in the design model.
It's also more powerful.
But the tradeoff is ugly within the context of the nature of the UI.
Git is like C++, it has a lot of features, the UI is not well thought out and it creates countless corner cases.
Git was not designed to focus on the core cases, making things simple.
Git is one of the great 'litmus tests' for product design thinkers. People who don't understand why git is problematic (even if they are really good at it) I think would have trouble with product design.
Git is more popular because Github used Git and Github was better than google code or sourceforge. Bitbucket got like 80% of the way there but was always a few steps behind. Had bitbucket taken off rather than github (which is much more to do with the web UI and network effects than the underlying VCS), we'd all be using hg now.
This sort of developer blindness once you have learned something is why we need user interface people as a whole separate discipline.
The "concept" of resetting? "git reset" does different things in one command: there is no one concept. It can discard your staged changes and working tree so that your workspace looks like your head. It can move your head ref while doing that. It can move your head without changing the working tree. It can interactively stage the changes to another commit (e.g. to selectively revert).
Git's hard when you see googling for syntax as a failure in the system. If you see getting SO answers as working as designed, it's quite easy. The main learning curve is just the idea of everything being branched, which is an increasingly common concept in many spaces.
I slightly disagree. I think git is simple, but the UX (the way the commands and flags are designed) is really bad so that's why it's perceived as hard.
It's the case with most UNIX CLI tools and if the author's complaints are true, do we then have to change all UNIX CLI tools? Maybe? The reality is we can't and probably don't need to.
"Truly understood" is close to a holy church I guess.
However it's perhaps really that too many people are thinking they need to use git because their church says so and then have to deal with the self chosen authority.
It's years ago, but I recall as a rookie I found mercurial way more approachable and easy to grok. Still distributed and a similar model to git, but considerably more approachable CLI interface and manpages.
It doesn't matter how easy the concept is if the information it contains is not something I can estimate, and in the case of git all the power is coming from indirection, which is famously inestimable stuff.
Can I use git like a simpleton? Absolutely. Can I gracefully recover from errors in its application? Nope, it never happens. It's a chainsaw and I ultimately have to solve the problem by using it like one.
I like to say that git is a "white box". You need to understand the internals to be able to use it.
Contrast this with "black boxes" where you don't have to or even can't understand what's going on.
Some would argue that software shouldn't be built that way, but I will respectfully disagree. It's not an end user facing consumer product, it's a tool for professionals. You wouldn't expect anyone to operate a table saw or a milling machine without some understanding of what's inside the machine.
I do agree that the git user interface is inconsistent and full of caveats. But as long as you understand it's just a directed acyclic graph of commits, you can dig yourself out of any hole you get into.
"You wouldn't expect anyone to operate a table saw"
? Coming from a family of carpenters, I can assure you none of them really know that much at all about the internals of the table saw. Maybe a little bit.
The 'black box' analogy is upside down: there are a million artifacts of the computer that you use every day for which you have no understanding. We use encapsulated concepts to be able to leverage much more complexity than we would otherwise.
Having to deal with the 'inner workings' of git, is like having to have the instruction set for the chipset your computer is running on handy 'just in case'.
Git is very powerful, but very poorly designed from a product perspective, there was no 'strategy' just 'add commands and flags that do this and that'.
When products expose considerably more complexity than they need to for most uses cases, it's just bad design.
I also have a sneaking suspicion that so many 'git experts' are really just expert within a fairly narrow range of commands/options - because when I start to ask more detailed questions, the answers are never clear.
No other product has consistently caused so much confusion, wasted time. Though 95% of my personal interactions are fine, there are just too many times where we have Senior Developers, huddled on someone's machine, trying to solve some arcane problem - this is the 'not very hidden cost' of git.
I would say: "Within Git, there is a much smaller and clearer CVS struggling to get out."
Having used a few of these version controls over the years each one has its kind of 'core' strength. Most of them evolved next to each other and borrowed the shorthand of each other and copied each others API/GUI/CLI (mostly), and the shorthand of a physical library. git on the other hand stands alone in its interface. in many source controls 'checkout' for example means I get exclusive control of this file on this branch. Where as in git it does not mean that at all. That is where much of the misunderstanding comes in for git. The commands are kind of the same names but do very different things.
I've always found linear algebra to be far simpler than any other advanced mathematics. It's basically just a lot of book-keeping and consequences from that. Yet I know smart people who failed it multiple times and had to change majors to avoid it. That makes me pause before dismissing people who complain about it.
The article has a better way to assess difficulty, based on how easy it is to teach other how to use it.
Mental model to use SVN for example was quite simplified.
No connection to the server no committing - no confusion about local vs remote.
Branching only on the server, merging totally useless - no branches, no merging, no conflicts.
Want to have your local development versioned - zipfile + date time.
I would never go back to that, but from people complains some might want to.
Do you really think the .. and ... notations semantic differences between git-log and git-diff are reasonable?
I personally think if a..b in git log shows me a set of commits then a..b in git diff should show me the code contained within those commits, the patch files that would generate from them.
The only concept that I can't put into my muscle memory is reverting changes for one file before commit. This is very easy in SVN but for some reason it's not intuitive git (at least for me), why there can't be something like `git revert filename`. Thankfully I have GitKraren that is helping me with things like that.
Git is hard because it precisely models the complexities of concurrently modifying source code on multiple computers. It explicitly models all of the concepts and operations that are relevant in that domain - branching, merging, my local changes, the server that my local branch is kept in sync with, rewriting local history, rewriting public history. Can you shoot yourself in the foot? Absolutely, because this stuff really is non-trivial. Could it be made easier? Yes, by limiting what operations you're even allowed to make, and streamlining those (c.f. git flow).
> Why can't there be an equivalent of stash that keeps track of which parts were added and which weren't?
What do you mean by this? It sounds like how stash already works.
> If switching branches wouldn't conflict with my current change, why do I have to stash/checkout/unstash instead of just doing it?
This is how git has worked for years: you can checkout a non-conflicting branch without stashing.
> Why can't I pull without fetching?
Have you customized Git to not support this?
> Why do I have to detach from a branch before deleting it?
When does it make sense to do this? I can understand deleting a remote branch (which doesn’t require this) but deleting the current local branch doesn’t seem to make sense in any normal workflow.
> Why can't there be an equivalent of stash that keeps track of which parts were added and which weren't?
But git stash does keep track of what it added?
> If switching branches wouldn't conflict with my current change, why do I have to stash/checkout/unstash instead of just doing it?
If your current changes apply to files which haven't changed between said branches, you don't need to stash your changes when switching between them.
> Why can't I pull without fetching?
The command for that is `git merge`.
> Why will none of the 5 or so push configurations just do "push the current branch to the branch of the same name on the remote"?
The command for that is `git push origin HEAD`.
> Why is there no way to stop git from setting master as the upstream every time I do git checkout -b myfeature origin/master?
The option for that is `--no-track`.
> Why do I have to detach from a branch before deleting it?
Because the `git branch` command never changes the working tree, which in this case uses the branch name to identify its location. If the branch were to be deleted without first detaching (or switching to a different branch), stuff would break.
It would be great to have a GUI tool that allows you to do common tasks with a sort of Wizard interface with validation, precise human-understandable explanations, delayed execution (like GParted) and Undo functions. Personally, I don't use GUI tools for Git because they are either as complex as the command line version or I'm afraid they do something under the hood that is not what I intended. I'm not sure GUI tools for Git are programmed in a way that makes data loss impossible.
Some kind of troubleshooter GUI tool that covers 90% of all use cases would be great. I'd certainly be willing to pay for it.
Exactly what I feel about this tool. I don't get it what is the structure of the inner tree of git changes. Once I though I understand those graphical graphs where branches go out of other branches and than after some commits are merged back. But then I learnt something more and I lost confidence in what I believed before.
Arguments against git being 'too hard' seem to fall into these categories:
* It's not actually hard.
** You don't understand it. Everyone else is fine with it. You just haven't spent the time to understand it like everyone else has.
** Ok maybe lots of people don't understand it. They just haven't spent the time to understand it like I and others have.
* It is actually hard.
** You're not intelligent enough to understand it, but everyone else is.
** Ok maybe lots of people aren't intelligent enough to understand it, but that doesn't matter because I am and so are others.
IMHO the more intelligent response is:
* If people think it's hard, that's a problem, and we can use our understanding / intelligence to help make a version control system (layered on git if that works) that doesn't require the depth of understanding or intelligence to work with - for everyone.
I've worked with thousands of developers and my experience is that even the brightest still make mistakes when given sharp tools, and when you're just trying to get your job done but you've tied yourself into a knot with distributed tools that try to help you deal with merges of turing-complete text, you can have a bad afternoon.
I'm hoping darcs / pijul / something else a bit more 'friendly' becomes popular and those who want to concentrate on their code and not their tools can get some time back.
If you want simple and intuitive interface, then use Source Safe. If you want your team to be performant, then you have to deal with the complexity of parallel work and merges, where git shines.
Ask your manager, which problem is the problem for him.
Git exposes all of its complexity at installation, which means that you are able to do any amount of damage from minute one. There are no cascading layers of abstraction that map onto the user's comfort level with git.
Git also doesn't prescribe workflows. Overtime, people have come up with standard workflows, but there are too many of them and they all have different mental models. The issue is that most of these workflows are only marginally better/worse than each other and don't necessarily provide additional functionality in any sense. It would be much better if there was only one way of doing things in git. It would make things marginally inconvenient for many, but the marginal loss of productivity would be more than made up by a consistent mental model and the increased reliability of the 'canon' workflow.
Last, and certainly my biggest complaint is the terrible UX and the semantics they convey. It is almost as though the creators went out of their way to have naming schemes at odds with natural language.
I hope someone builds a keras-like tool for git. Interoperable with the tensorflow (v1) that is the git underneath, but exposes a much easier and in most cases feature complete set of abstractions that work for 99% of its users.
I see a lot of criticism but not very much any suggestion that would avoid users having to learn how to rebase on an origin master branch or how to force push when they rewrite history. All the git interfaces, including github's web interface particularly, are fine to fix a typo but not really to iterate and create a perfect history of commits.
Based on my experience with users who did not have a programming background, there is no reason for letting them know about neither rebase nor rewriting history. If you are rewriting history, you are already ahead of the curve and you can use the command line. Commit, push, pull, branch and merge are all 90% of users need, and those last two are already an advanced topic.
For a good example of "user friendly git" I suggest taking a look at mercurial.
Resisting GUI's is not a good idea. The trick to learning is to always have `gitk --all` or a similar viewer open in another window.
Also instead of `git add` / `git commmit`, use `git gui`, but for most other things stick to the CLI.
Having said that use a GUI, github desktop is terrible. It tries to make things easier and as a result takes you away from git's standard terminology, so it's impossible to understand what it does.
Something I found teaching other people is it helps a lot if you haven't learnt SVN before.
The problem, at least for me, was the complexity of the model which makes the whole thing super scary when you've just started using it. That's where GUI tools come useful, as people are generally less scared of GUI tools - they make you feel there's less of chance of making a mistake because you put the trust in the tool to stop them doing something obviously stupid. However IME that trust is not really deserved as most of the GUI tools will just as happily let you mess up your repository...
You have to understand a lot of things before you can somewhat comfortably use git, much more than something like P4.
Git might not be easy, but it's not complex, it's simple. There are basically only four concepts: blobs, trees, commits, and refs. Which systems (not just version control - systems in general) are simpler?
The main problem that I see with using git is that when you are part of a team, what kind of release and branching strategy should you use.
It's comparatively easy with one person team but becomes complicated with a team and even more if it's an open source project and now you have individual devs contributing their changes.
I use the first two so much that I've dedicated a keyboard macro key to each.
Deleted Comment
After growing up and becoming wiser I came to understand I did this all because I didn’t invest the time to learn how these complex things worked. It also made me feel smart to write more code. Big mistake.
I can’t help but think a little bit of this pattern rears it’s head as the motivation for things like git GUIs.
There will be a maintenance burden and no matter how careful you are there will be bugs.
I write scripts for complex but infrequently used operations and drop them in ~/bin
I disagree. In my personal experience, learning git took a lot of trial and error, but now whatever terminal I sit down in front of, I know exactly which commands I have to run to do what I want in git. When using a GUI, it's fine for the easy/common stuff, but if I want to do something more complex I have to figure out how to dig through the options provided by the tool to get the result I want.
This insight why git, like other tools, is stupidely designed.
The "wrong" defaults and UX is the DEFAULT, and each USER must learn it.
Meaning:
UX * N Users = Wasted time and money
---
If I present you a screenshoot of a (real!) business apps with mis-aligned buttons, some put in weird places that mean different things that them are supposing by their labels, that use non-standard interactions that mix different UI paradigms, with rare color combinations (aka: vomit palette) , all in a SINGLE window (!), you think the solution is resist a better interface? Why we mock "regular" users or their enterprise providers, but somehow can't with ourselves?
I don't know why so many developers live in constant Stockholm syndrome and like it, and resist any suggestion to improve.
When anyone ask me about the tools I use (specially asked when somebody look at me using the terminal), if I liked, i say "No, this is the bad and ancient way, but we are here, stuck on this.."
IMHO, a good git GUI would show exactly what commands are being run (so it is useful as a learning tool) and their result and allow it being used along side the cli.
I use magit extensively and it has all these properties.
If you want to do something more complex, the reasonable answer is usually to delete the directory and clone again.
Deleted Comment
The fact is, once I got over myself and sucked it up and got my head around it, it really only took 2 days of effort to grok what I was doing and now it's easy.
So biggest advice I can offer is this: Get over it and get on with it. It seems like a pain in the ass now, trust me I know, but you'll thank yourself for making the effort in the long run.
Thankfully there are tools that make it less horrible. Git Tower and Visual Studio integration come to mind as examples.
It's sad, however, that there's not been an overhaul of the git commandline into something coherent and usable.
It avoids much of the confusion from the checkout command, which does very different things depending on what flags you pass it. That said, this is only one git command. The rest still has plenty of room for confusion.
They’ve also added some guiding comments to various commands (like rebase) that make the CLI more user friendly.
I think checkout was the worst offender, because of how necessary it’s use was for most workflows. Branch could probably use some pruning, too.
I think it really comes down to a difference in philosophy in terms of learning how to use tools. In the past, one had to read the documentation to figure out how to use a tool. So, for instance, running git --help or git branch --help would give the information needed.
Now having a what's considered an intuitive interface is expected, which is why many people have problems using tools where the documentation is there, but people don't want to take the time to read it.
This is rarely the case. Sometimes at the end you get nothing but a wet handshake. Think about vim: it is cryptic, does everything different than everything else out there , but it gives you something in return.
If you make your tool less inutive, but give users nothing in return, you are doing it wrong. If the interface of your tool does it one way in this corner and another way in that corner — so if you are inconsistent without good reason — you are doing it wrong.
Interfaces are about clear communication. Interfaces are the difference between a rugged 50k$ Arri Alexa cinema camera and a 200$ camcorder: the more Alexa has physical buttons and knobs for important things precisely in the locations where they should be, precisely behaving in the way they are expected. The cheap camcorder has buttons, encoders and levers sprinkled over it seemingly random.
The interface of a tool is good when it can be used intuitively even under stress, in bad weather and on drugs. This is ehat we all should aim for imo: tools that are more powerful/expressive AND more intuitive at the same time.
I like reading manuals, but not for things that could have been totally obvious if somebody spent a split second thinking about how to communicate it clearly.
That said, sometimes when you are frustrated by having to add special cases to your code, it's not your fault, it's because you're modelling a badly designed system in the first place.
I disagree. It is quite slow and makes the wrong assumption that everything should be text.
But yeah, I fear people have issues with Git because unfortunately they reflect upon their experiences with other SCMs (like Clearcase, SVN, RCS/CVS, whatever) and think the same terminology and concepts apply in Git and then it goes wrong.
Git is not really rocket science to use. People who find Git difficult or nonsensical should spend 4+4 hours of their weekend playing with Git while reading Pro Git. It's available for free at https://git-scm.com/book/en/v2.
Specifically, read chapters 2, 3, 5, and parts of 7.
You should intentionally skip chapter 10, more than likely you don't need it.
Keep Pro Git handy and come back when you've a specific need.
https://git-scm.com/docs/git-switch
Avoiding the rebase/edit/ammend/etc cycle is a huge time saver. What I really want it to do is be able to select a random hunk and move it as well...
[0] which was created before my time at Axosoft, so I'm not that biased :-P
Explain why.
Within our lifetimes, an interaction most users have with a computer could be just thinking about something to cause an action. I don't want to have to see a GUI in my brain to do that. Similarly, not everyone likes having to use what is traditionally called a GUI.
For git, I prefer the CLI, though I use some helpers for completion, I have some scripts I wrote to show remote and local branches with their authors in different states of merge, etc. My guess is that in your GUI, you don't have that level of customization, and probably didn't even think it was an option. That's the problem with GUIs for me.
Thats why, not everyone prefer CLI, if you are the one who learn better with GUI then resisting GUI's is not a good idea
The whole point of the UI is so that your workflow is simplified without having to understand the exact inner workings of it all.
GHDesktop’s simplicity means that most of time I don’t have to call 4 commands to just check out a new repository or PR because one click runs all those 4 commands and more.
As simple as it is, lately I rarely have to use the CLI (which however I still use because I rebase and fixup)
The fact that “takes you away from the terminology” sounds like people complaining that Windows 95 users don’t know what MKDIR means: That’s the whole point of UIs.
This sounds ominious.
I would completely disagree with this, anything that adds layers between you and git creates more opportunities for misunderstanding and corner cases.
Resisting a feature branch/merge workflow is what's a bad idea.
gitk is like an anchor for me to understand where I stand in given repo.
Make sure to set default view to display all branches and mark branch sides.
Deleted Comment
Git is the bad boyfriend of the developer community. If anything bad happens it was your fault. If you ask it to do something and it does something else, it was your fault, and also you are stupid. If you ever make a mistake, you will be punished for it with a long drawn out cycle of embarrassment. No matter what happens, it was not git's fault, it was your fault.
Good software is not like that. Good software is the opposite of all of that. Git is the industry standard, and I have just accepted that we aren't going to get anything better, but whereas it might make sense for the Linux kernel dev community, it is not good software, and I suspect that it's not just the UI that's the problem.
Lots of non-devs also have the problem of wanting to have multiple people edit the same document, track changes, and occasionally merge them. I would never recommend that they use git, and I see no evidence that it is ever spreading beyond the dev community in any significant way. There's a good reason for that.
The author's idea of putting an abstraction on top of git is the way to go. As an analogy, Git is a great toolbox, but sometimes you need a plumber. I like how apt and apt-get came into being on Ubuntu.
The comments about the logical inconsistencies in Gits command line are a clue.
When is the last time you wrote a CLI utility and listed all of the commands, subcommands, and options to make sure they all had a consistent look and feel? Most single-author tools do not do this. It is a consequence of developing in a vacuum. Team-based development allows other eyes to look at it and say "why is checkout used during branch in a different way then branches are checked out?". Git came from, essentially, one person. That's part of it.
But that is also a legacy of Unix/BSD. Consider `du` and `find`. Both have an option for max depth, but is it --max-depth, -maxdepth, --maxdepth, -d, or -m (or even -L for `tree`). There is a lack of consistency that is a rite of passive for Unix/BSD acolytes that even Gnu didn't fix... C'est la vie? Or maybe a /bin rewrite? bahahahaa who am I kidding.
There's no question Git is a powerful tool, it just needs to evolve and gain some consistency. And I think the answer is a higher level abstraction. And for the love of Benji, NOT a GUI.
I think what's interesting is that, in the space of programming language development, languages that tend to have a more consistent feel across the language (such as Clojure, Python to some extent) tend to have BDFLs and came from a single person.
https://blog.carlmjohnson.net/post/2018/git-gud/
Ready to be downvoted into oblivion for this, but: This is how a lot of the Linux/FOSS community is so it makes sense that Git is too, sadly.
Things have gotten a lot better with the attitude these days, but you know it's bad when StackOverflow needs to issue guidelines on being polite and how to answer questions without being rude/condescending.
I tried SVN one time, which is a little simpler, but still didn't catch on with the person I was showing it to.
IMO nothing remotely like version control nor anything that requires a command line is going to click for someone in a non-technical field.
As for non-devs editing the same document - unless that document is text (which typically it isn't for non-devs), I would probably not use git on them either.
This is a contentious statement. Fred Brooks himself calls the separate command language, which began with JCL on OS/360, a mistake.
You can't just say this without providing an example of what you think is good software, as, after all, good and bad are subjective and not agreed upon by all people for all things, as evidenced in this thread.
In fact, it's every fucking version control system other than Git.
https://news.ycombinator.com/item?id=25001539
This is the root of the author's issue. As another commented, git is born in a world where computers are mostly offline, people are highly technical, and will spend a lot of time manually crafting the messages they will send to the numerous collaborators. It is an alone-first software. What the author wants (and exactly what I want as well: https://news.ycombinator.com/item?id=25002318) is the complete opposite: a system that knows it's connected to other people, where changes are instantly propagated and easily visible, where the differentiator between "branches" is not "what computer does it reside on" but "who did it". That's the model behind GitHub, after all.
git is complex because it's working with a very complicated model that is not in line with what most people expect today. As I said in my other comment it seems that fossil works with that flow, but I haven't tried it. However what is sure is that it doesn't make sense to ask git to become what it fundamentally is not.
EDIT: There might be a solution with wrappers. When you look at git-annex assistant (https://git-annex.branchable.com/assistant/) you can see that the right amount of abstraction can provide something closer to what we expect... but at this point it's not git anymore, so we might as well start from scratch.
>Oh, I just pushed a change. I really didn’t wanna push that, so how do I undo it?
Is a Github problem, not a git problem. You might as well ask how to unsend an email. If you don't know what git push means, you shouldn't be using it and are playing with intellectual property fire.
The conflation of Github with git is responsible for a lot of confusion. Having Github be your first interaction with git is a disaster.
Regardless, there's no shortage of blog posts complaining about git being hard. But there is a shortage of effective, popular competitors. I think that, actually, many-chefs many-branch differential version control is just a hard problem and creating a simple model for it is much harder than complaining about git.
That is also a reasonable request.
I'm unable to fathom the notion that if a computer doesn't work the way people want, the answer is for people to adapt to the computer. The whole point of computers is to do things for people.
With physical messages, unsending has at least partial support. Before the mailman picks up from my porch, I can grab a sent message any time. If you FedEx the envelope, you can cancel before delivery. With a university's mail system, you can get the receiving department's admin to return something even later in the chain. And of course, you can always tell a recipient, "Hey, I sent you the wrong box, just send that back."
The reason email doesn't support unsending is not some essential property of messaging. It's just that at the time our email protocol was defined, both our hardware and software was pretty primitive, so we locked in a very primitive model of messaging. But note that more modern systems, like Slack and Facebook Messenger, happily let you unsend things. And consequently, they're effectively replacing email for most users.
Do you mean it's a problem only if you are "git push'ing" to a remote shared by those working on a software project?
OK, maybe. Even before github, most projects I knew of using git used that method. You can suggest nobody should, and try to educate people in a completely distributed workflow if you want, I suppose. That's not about github really.
With history if you make a vcs mistake, or realize iteratively after pushing that corrections are needed, your worthless threshing around trying to fix it becomes part of your project log forever, instead of just pushing the corrected tree with just the one corrected patch.
Git (the software) consists of two things. the git client (on your machine) and the git server (wherever you push).
It is most definitely not a GitHub problem if you pushed your changes to a local network git server, for example.
Whether you realize it or not, that's gatekeeping. The point of UX is to remove artificial gates. When people apologize for the gates instead of fixing them, well... That's tantamount to threatening people's livelihood. It's a lot easier to do that when you don't think of it that way, and it probably shouldn't be easy. "I understand it, you shouldn't work here if you don't" is literally, "Fuck you, I got mine," with different words.
> about git being hard. But there is a shortage of effective, popular competitors
There is only so much oxygen in a room. There is not space for a million solutions to every problem, and once the Hype Train has left the station all you have left is to make the fiction true, or try to accelerate the Trough of Disillusionment so we can get on with fixing the problems instead of deflecting.
And I say this as the only person on a large team fit to do anything approaching surgery on screwed up git repositories. There is frequently a degree of turf protection via "he's a bastard, but he's our bastard". No, he's just a bastard. I don't claim any responsibility, I just have to interact with him.
Git was primarily adopted because it solved those issues which were important ones at the time, people discovering git needed those tools and when discovering git would naturally come across and understand the trade-offs. IE: "I can't easily undo a change once it's on someone else's machine, instead I would need to issue a new change reverting it. But that's ok, because it means I can do as I like on my machine without screwing up the history for other people and only send a patch of specific changes when I'm ready."
The issue people now face is git has become so popular, because of those initial reasons, and we're dealing with a new set of problems which git never cared about.
"Project X is in a git repository, and I want to contribute a change".
This is a fundamentally different problem to the original problems git tried to solve. We're now in this weird space where most people using git are only using it because: it's what they already know, or the project they want to work on already uses git.
Requests like "I just pushed a change and didn't really want to" don't make much sense and don't matter much in the original use cases. Now many git projects use centralised hosting and a lot of people don't really care about git, just getting their work done, we now have this UX issue. The UX issue isn't a result of poor design or implementation in git, it's due to the motivations of users being fundamentally different now.
Sure you could argue that git should change or be easier, but then it would stop serving the original purpose. If people want a centralised source control with the ability to easily retract changes and have branches be the same across all nodes then really they just don't need what Git sets out to solve.
The issue is git is now dominant, and that forces people to use it even if they don't have the problems that git is really attempting to solve. That means they're stuck in a place of using a tool so they can collaborate, without getting any of the benefits of it. That's enough to drive anyone insane! It's like pushing a boat across land to get to another village when a boat is really to get to another continent, but no one makes cars because everyone's already boats.
We don't need "better" UX for git, we just need people to know about all the options, and part of that may include encouraging some people to choose more centralised options when it's a better fit for them.
My previous and current company use perforce but many people (often those who recently join) are decrying that perforce is less elegant than git, but, realistically and based on your own criteria it would be "better" for the connected case.
I'm personally a big fan of 'offline/local-first' being a thing, but I'm a sysadmin not a developer.
I have my problems with it, but once you understand it I find the workflow quite simple.
If you don't really need the decentralization I think it aligns quite well with how people expect version control to work. You make edits to your data, once you're done, you send them to the server to be shared with other people.
Ugh. The centralized model is better for companies, but ClearCase really makes its best to make your life miserable:
- You have to think twice before modifying a file, because the steps to be able to modify a file can take from 30 seconds (if you already created the activity) to a few minutes (if you have to create it)
- Activities are supposed to be like branches, summing up all the changes. But there is no way to see all changes in one go. It's click everywhere, waiting for the server to reply on each click.
- Because there is no way to display the branch content in any way other than envisioned by IBM, there is no way to discuss a changeset. No pull requests, no exchange, nothing.
- Horrible UI/UX all around. It's slow, it's unreadable, random bugs happen all the time where the only fix is to restart the service, .... and it's expensive.
I'm not advocating for a system that only works when online (although the fully integrated system of Google does sound good), just that it be architectured around a point of centralization. This is the way I'd like to use git:
- A branch created locally will be synhcronized and visible to everyone by default
- A branch that I manually tag as private won't, but it will still be saved on the server
- A branch that has a conflict between me and someone else will be marked locally in some way (maybe a second branch ?)
- Bonus: my working repo and staging area are also synhcronized to the server
Github is a parasite.
> the quality of the tech that is Git is a testament to GitHub being able to make it this far in the tech space
But in reality, Github makes Git more complex, because now you have to understand the concept of forks. Not only is there your local copy and an origin, there is a 3rd repository in play.
We're trying to assemble this from different pieces, without a clear idea if we can even get there from here, given all of the roadblocks Information and other Theories throw in the way.
I hope someday we meet in the middle with systems that can handle code and incidentally a bunch of other problem domains we also care about.
Deleted Comment
We have this already. It's called collaborative desktops over VNC ...
> the differentiator between "branches" is not "what computer does it reside on" but "who did it"
So you're into collaboration, but not on branches? I would have said branches related to specific units of functionality, streams of development or specific issues.
Definition of branches aside, this is the way old-style centralised VCS like CVS, Subversion actually work - and you can still use SVN if you want to ... or you can use git in that manner and never have to worry about it's more complex details.
The whole point of Git is that it addresses the specific problem that once you are disconnected you de facto have a branch. Once you push to remote its more like that ideal you're reaching for.
> at this point it's not git anymore, so we might as well start from scratch.
I'm sorry this is really quite hilarious. Go! Stop whinging and go do it!
> We have this already. It's called collaborative desktops over VNC ...
We still want a revision control system, things like commits and all.
> So you're into collaboration, but not on branches? I would have said branches related to specific units of functionality, streams of development or specific issues.
Depends on the workflow. Many people have long-lived branches, introducing big features/refactorings. Many other prefer short-lived branches, where one branch typically is used by a single person. I still think branches should be focused on topics, but the topic (and thus the branch) must be the same on all computers, instead of having one version locally, another one that is mapped to it but potentially has different content on the server, and 1 different branch per other user. How many times have we had to "oh you pushed on your branch, I have to get it first"
> Definition of branches aside, this is the way old-style centralised VCS like CVS, Subversion actually work - and you can still use SVN if you want to ... or you can use git in that manner and never have to worry about it's more complex details.
Yep, that's the model: one place where people synchronize. The issue with those was not the centralization (look at GitHub), it was the lock mechanism. I can use git to replicate it, or I can use the folder.bak and folder.v1.final on a NAS method. It's not because it's possible that it's desirable
> I'm sorry this is really quite hilarious. Go! Stop whinging and go do it!
Ah, so it's not possible to criticize work until we have developed a complete alternative ?
— Isaac Wolkerstorfer
http://twitter.com/agnoster/status/44636629423497217
We have files, which are inert objects and form a "file space". We have diffs. Diffs can "act" on a file to produce a new file or a conflict --- we call this as "applying a patch". Mathematicians would call it a "group(oid) action". Diffs are a groupoid because (1) there's an identity diff that does nothing, (2) diffs can be smashed together, (3) if the smashing of diffs succeeds, the operation of concatenation is associative, (4) all diffs are invertible. If we were to delete added lines and add the deleted lines, this inverts the diff.
Finally, we have a rooted DAG where each node is a diff, and the root is the empty diff. Git queries enable to manipulate paths in the DAG, which corresponds to smashing together diffs along a path to produce a file.
If one groks this, the rest of git is a pretty poor interface on top of this nice mathematical structure.
For more physics-y applications of torsors, check out the baez article: https://math.ucr.edu/home/baez/torsors.html
- You have a branch `master`.
- You have a branch `feature` which contains commit C, which conflicts with `master`.
- You merge `feature` into `master`, fixing conflicts.
- You log the commits of `master`.
Wait, how can 2 commits in a row have a diff that modifies the code in the same way? Well, mind you, the diff of a commit doesn't correspond to the moment the patch of the commit was added to the current branch, it only corresponds to the moment it was added to its own branch.Well why didn't you just say so!
But isn't the core idea of Git, everyone has their own repository and they share branches, kind of complicated and tricky? In my experience the developers I see having problems with Git are having trouble with the hard stuff, not the easy bits like committing and pushing a change.
Git's--and Mercurial's--secret sauce is the directed acyclic graph of commits.
Everything else is window dressing. It's complicated if you're used to a linear sequence of commits, but it's not too hard once you grasp the tree structure.
All operations are operations that manipulate (or share) the DAG, so it now becomes a matter of mapping how you want to manipulate the DAG onto the command set the tool gives you.
Git's toolset was designed by a dozen madmen that didn't talk to each other, so it's a loosely connected set of tools with conflicting syntax and meaning. Mercurial's toolset was designed to be used, so if you know the right terminology, you can easily figure out what command to write. Want to commit something? It's probably hg commit. Want to rebase? It's probably hg rebase. Etc.
Git exposes unnecessary complexity. But it won the DVCS popularity contest, so we're stuck with it. I wish something else had won. Oh well...
That being said, I know there are some who have trouble with Git. But IMO it isn't because Git is hard, but because they don't have to truly understand Git to use it. That's how easy it is.
A copy&paste of my previous comment:
Everybody's brain is different but I actually understand all of git's internals (the "plumbing") but it doesn't help me with the git CLI (the "porcelain").
Yes, I know that Git is a DAG (Directed Acyclic Graph), and that HEAD is a pointer, and the file format of BLOBs and SHAs, etc. If I were to implement a DVCS, I would inevitably end up reinventing many of the same technical architecture decisions that Linus came up with. But none of that insider knowledge really helps me remember git syntax if I haven't been using it in more than a month. Even though I grok git's mental model, I still can't answer the top-voted "git" questions on Stackoverflow without a cheat sheet: https://stackoverflow.com/questions/tagged/git?tab=Votes
The git UI and unintuitive syntax is just too hard for me to remember unless I use it every day.
Also to add.. the concept of "git index" as a staging area adds some complexity as well. Yes, there are good reasons for it (1) it lets one craft a specific subset instead of all changed files to commit and (2) it's a performance boost because a Big-O type O(n) loop runs faster when iterating through the staging index (small "n" of dozens) to detect changes instead of looping through the entire source code tree (large "n" of 10,000+ files in a big repo). But that flexibility adds an extra cognitive burden when a newbie just wants to save a "backup snapshot of the repo". For a newbie, the extra indirection layer of "staging index" seems superfluous and confusing. That's why some present an alternative porcelain to git that doesn't expose the staging concept: e.g. https://gitless.com/
(To clarify, I'm not recommending Gitless but just giving an example of why some felt motivated to simplify Git's porcelain.)
All sorts of workflows become substantially more difficult (if not impossible) with kitchen sink commits. Undoing a single-line change, for instance. I dislike large pull requests, let alone commits that introduce a half dozen different changes.
Sure, if you’re really disciplined you can produce small commits without staging, by committing as you go along, but you’re breaking flow every time you commit in this style.
I say all this because I would love a CLI that has half-way sane handling of (e.g.) restoring staged, deleted files; doesn’t conflate restoring files with switching branches; has consistency of flags between commands (such as commit vs stash message); etc., etc. I should try gitless ;)
Simple needs have simple answers.
Sure, you can ask "why are there two commands?", but this is not so much an issue of cognitive burden as of typing burden. If you only want one thing, you only have to know how to do one thing. If you don't want to know why the procedure does what it does, you don't have to.This was surprising to me, and shows how different people's experiences of git can be. My workplace switched to git from an obsolete centralized VCS earlier this year, and I could easily answer these.
Something like this is probably where the line between those in this thread who agree that git is too hard, and those who think the detractors are just lazy and stupid, runs. Folks, people are more different than you expect!
This sounds like you just don't use or need those things much, which is fine if it works for you. Of the top 10, I can answer 9 of them without doing any research because I've used these commands a lot and they've become a part of my workflow. The one I'm missing? I've never renamed a git branch. If I needed to, I'd probably just do git branch --help or google it and figure it out in five seconds.
You don't need to commit every command of the program to memory. Just like anything else in tech, knowing how to find the knowledge you need is good enough.
For the questions, what's bad with quick help on SO? It's maybe less effective than reading the documentation that ships with git itself but for sure much more popular and less to read.
Git truly is a command-line utility, little known is that it ships with more than one gui in the base package out of the box. handling the staging area with git gui for example is straight forward unless you have more than 5000 unstaged files, then the gui informs you about it's limit and mass handling is far easier on the command-line anyway.
The reason I want to stick to the basics is because of one interesting thing I've noticed: a lot of engineers sincerely believe that they are git experts when they are nowhere close. And until I locked down the GitHub repo with admin privileges, that was a dangerous thing. So I'm trying to work a system where no one in a team where not everyone is truly expert at git only uses the basic commandset from git.
One thing I can say again to emphasize - git maybe the simplest Vcs you've used, but it's not a simple tool, and its most definitely not intuitive for everyone. If it is for you, that's great, but maybe there's a lesson here about how not everyone's brains are wired the same.
Once, when leaving a job, I decided to copy all of my local WIP branches to the server.
I whipped out this fancy --mirror option I had just heard of:
Surprise! All branches on the remote repo got wiped. My local refs replaced the refs on the remote.Somehow I found the right commits floating around in the git ether. I was able to recreate the branches, but I had to recreate their names by reading the commit log.
Did I mention this happened on my way out the door from a job? In retrospect, I shouldn't have panicked so much -- there were daily backups -- but the sheer terror I felt has made me read the man pages really closely to this day.
This means it isn't hard. If you are capable of understanding algorithms of any complexity you should be able to learn how to use git (and how much of it) without treading on ground that is dangerous for you to use. All of this "it's too hard" rhetoric is infantilising or coddling people who frankly shouldn't be trusted to code anything of importance anyway. There's no shame in admitting your own limitations, but there is definitely shame in lowering the bar for others so much you are actively harming the industry.
This is both good and bad. I get a lot done, but not always as efficiently as possible, and I do find myself realizing, down the road, that I didn’t need to do it that way.
But it’s entirely possible to get caught in “tool rabbitholes,” where the main goal becomes subservient to the infrastructure.
I remember dealing with folks that would spend three days, writing CLI tools that saved, maybe two hours, over the course of a year.
These commands will get you 99% of the way:
- git status
- git branch
- git pull
- git add
- git commit
- git diff
- git merge
- git push
- git checkout
For everything else there's StackOverflow, but the info in there comes with the risk of being stale.
--------------
Edit commit abaeb3b4: Add missing commands and improve formatting
Edit commit 842babda: Add git checkout
That's a great summary for the majority of Git users. I am still motivating people to spend the time to learn it "properly" if they're using Git daily.
First of all, it will make them more efficient. I've seen too many people literally redoing their changes, because a cherry-pick/rebase is "an operation they don't understand".
Secondly, they will be able to solve most issues when (not if) they occur. Sure, I am more than happy to help my colleagues solving their issues. From "why are those changes in my PR" to "our Jenkins job went rogue and now we've got hundreds of MB of data in our repository that we would like to remove". But the time of me explaining things the "learning by doing" style would be better spent actually learning Git.
So instead of SELECT you'd have FETCH, PULL, CHECKOUT, CLONE, READ, PEEK, and OBSERVE. And each of them could in some cases also modify or even delete the data depending on the switches.
Imagine there was no division between DML and DDL - you just have to remember which option switches change the schema in addition to doing some other things.
And then people would say "SQL is very simple, just learn relational algebra".
That's how I feel about git :)
With SQL I know for sure I can't break the database by doing a select. I know I can't change schema by doing a DML.
With git I'm pretty sure I can't break anything by doing git status, but other than that all bets are off.
In your list of shout commands I don't see anything that could be used for merging? I guess the "language" of git could be tweaked to make it more consistent, but otherwise the problems it is trying to solve are more complex than what could be dealt with in a SQL dialect.
But the moment I could import SVN to git I immediately switched to Git for everything. And Mercurial... I guess it's a matter of preference, but I personally never got the hang of it. And the fact that they had both SVN style continuous IDs AND hashes was deeply confusing to me.
The only thing I did find confusing in the beginning was a) the distinction between pull and fetch. b) getting used to the fact that I don't really care about continuous IDs (or hashes for the most part ) and think more about commits relative to where I currently am.
In addition to that things such as `git add -p` or `tig` are so much more convenient compared to other VCS CLIs. But even if CLI isn't what you want we're now a couple years beyond having beautiful third party Git GUIs
I click on the file and click on "unstage". I don't know why people insist on using the command line for their dvcs. Is it even possible to selectively unstage or reset only a part of a file without a GUI?
The git CLI tool isn't great either -- that's probably the hardest part of git.
I still miss Mercurial. Unfortunately most people moved to Git so I also moved to it.
[1] https://www.mercurial-scm.org/wiki/GitExtension
The Lemming Effect.
I think this is the crucial part. Git will come off as difficult and strange if you're used to using a centralized VCS, and expect Git to work like it. But that isn't really indicative of Git's own complexity, just its differentness.
For example, the concepts of "ours" and "theirs" when looking at changes depends on the current operation mode (rebase vs merge).
Merging is unsafe-by-default, because it auto-merges even if both branches have modifications to the same file, and there is no guarantee that the resulting file is correct.
There are numerous ways to collaborate on a git repo, with vastly different performance/usability implications, none of which is obvious when you start up (merging remote into local, rebasing local onto remote, squashing local commits; patches vs pushes).
Not to mention that, for teams that work with a centralized remote repo, the whole concept of local tracking branches adds mental overhead for nothing, and extra work every time you want to push a change to a remote branch. You have to first pull, even if your changes and the remote ones don't touch the same files. Which of course means that, if you had a dirty worktree, you actually need to run 3 commands - one to stash your changes, one to pull, the actual push, and now an unstash.
It's also more powerful.
But the tradeoff is ugly within the context of the nature of the UI.
Git is like C++, it has a lot of features, the UI is not well thought out and it creates countless corner cases.
Git was not designed to focus on the core cases, making things simple.
Git is one of the great 'litmus tests' for product design thinkers. People who don't understand why git is problematic (even if they are really good at it) I think would have trouble with product design.
The "concept" of resetting? "git reset" does different things in one command: there is no one concept. It can discard your staged changes and working tree so that your workspace looks like your head. It can move your head ref while doing that. It can move your head without changing the working tree. It can interactively stage the changes to another commit (e.g. to selectively revert).
However it's perhaps really that too many people are thinking they need to use git because their church says so and then have to deal with the self chosen authority.
You are setting a very low bar.
https://en.wikipedia.org/wiki/Darcs#Model
http://darcs.net/QuickStart
http://darcs.net/
https://darcsbook.acmelabs.space/
Can I use git like a simpleton? Absolutely. Can I gracefully recover from errors in its application? Nope, it never happens. It's a chainsaw and I ultimately have to solve the problem by using it like one.
I like to say that git is a "white box". You need to understand the internals to be able to use it.
Contrast this with "black boxes" where you don't have to or even can't understand what's going on.
Some would argue that software shouldn't be built that way, but I will respectfully disagree. It's not an end user facing consumer product, it's a tool for professionals. You wouldn't expect anyone to operate a table saw or a milling machine without some understanding of what's inside the machine.
I do agree that the git user interface is inconsistent and full of caveats. But as long as you understand it's just a directed acyclic graph of commits, you can dig yourself out of any hole you get into.
? Coming from a family of carpenters, I can assure you none of them really know that much at all about the internals of the table saw. Maybe a little bit.
The 'black box' analogy is upside down: there are a million artifacts of the computer that you use every day for which you have no understanding. We use encapsulated concepts to be able to leverage much more complexity than we would otherwise.
Having to deal with the 'inner workings' of git, is like having to have the instruction set for the chipset your computer is running on handy 'just in case'.
Git is very powerful, but very poorly designed from a product perspective, there was no 'strategy' just 'add commands and flags that do this and that'.
When products expose considerably more complexity than they need to for most uses cases, it's just bad design.
I also have a sneaking suspicion that so many 'git experts' are really just expert within a fairly narrow range of commands/options - because when I start to ask more detailed questions, the answers are never clear.
No other product has consistently caused so much confusion, wasted time. Though 95% of my personal interactions are fine, there are just too many times where we have Senior Developers, huddled on someone's machine, trying to solve some arcane problem - this is the 'not very hidden cost' of git.
I would say: "Within Git, there is a much smaller and clearer CVS struggling to get out."
Deleted Comment
Deleted Comment
The article has a better way to assess difficulty, based on how easy it is to teach other how to use it.
No connection to the server no committing - no confusion about local vs remote. Branching only on the server, merging totally useless - no branches, no merging, no conflicts. Want to have your local development versioned - zipfile + date time.
I would never go back to that, but from people complains some might want to.
I personally think if a..b in git log shows me a set of commits then a..b in git diff should show me the code contained within those commits, the patch files that would generate from them.
I guess this is a foolish expectation?
https://stevelosh.com/blog/2009/08/a-guide-to-branching-in-m...
git restore filename
If switching branches wouldn't conflict with my current change, why do I have to stash/checkout/unstash instead of just doing it?
Why can't I pull without fetching?
Why will none of the 5 or so push configurations just do "push the current branch to the branch of the same name on the remote"?
Why is there no way to stop git from setting master as the upstream every time I do git checkout -b myfeature origin/master?
Why do I have to detach from a branch before deleting it?
None of this stuff is inherent to the problem or due to being a precise model of things; quite the opposite.
What do you mean by this? It sounds like how stash already works.
> If switching branches wouldn't conflict with my current change, why do I have to stash/checkout/unstash instead of just doing it?
This is how git has worked for years: you can checkout a non-conflicting branch without stashing.
> Why can't I pull without fetching?
Have you customized Git to not support this?
> Why do I have to detach from a branch before deleting it?
When does it make sense to do this? I can understand deleting a remote branch (which doesn’t require this) but deleting the current local branch doesn’t seem to make sense in any normal workflow.
But git stash does keep track of what it added?
> If switching branches wouldn't conflict with my current change, why do I have to stash/checkout/unstash instead of just doing it?
If your current changes apply to files which haven't changed between said branches, you don't need to stash your changes when switching between them.
> Why can't I pull without fetching?
The command for that is `git merge`.
> Why will none of the 5 or so push configurations just do "push the current branch to the branch of the same name on the remote"?
The command for that is `git push origin HEAD`.
> Why is there no way to stop git from setting master as the upstream every time I do git checkout -b myfeature origin/master?
The option for that is `--no-track`.
> Why do I have to detach from a branch before deleting it?
Because the `git branch` command never changes the working tree, which in this case uses the branch name to identify its location. If the branch were to be deleted without first detaching (or switching to a different branch), stuff would break.
2. See 1.
3. `git pull` by definition conducts a fetch because it Incorporates changes from a remote repository into the current branch.
4. Use `git config push.default current`.
5. Use `git branch --no-track new existing`.
6. I assume this is something to do with the reflog.
Some kind of troubleshooter GUI tool that covers 90% of all use cases would be great. I'd certainly be willing to pay for it.
* It's not actually hard.
* It is actually hard. IMHO the more intelligent response is:* If people think it's hard, that's a problem, and we can use our understanding / intelligence to help make a version control system (layered on git if that works) that doesn't require the depth of understanding or intelligence to work with - for everyone.
I've worked with thousands of developers and my experience is that even the brightest still make mistakes when given sharp tools, and when you're just trying to get your job done but you've tied yourself into a knot with distributed tools that try to help you deal with merges of turing-complete text, you can have a bad afternoon.
I'm hoping darcs / pijul / something else a bit more 'friendly' becomes popular and those who want to concentrate on their code and not their tools can get some time back.
Ask your manager, which problem is the problem for him.
* It is too powerful
* It is not prescriptive
* It has horrifyingly bad UX/semantics
Git exposes all of its complexity at installation, which means that you are able to do any amount of damage from minute one. There are no cascading layers of abstraction that map onto the user's comfort level with git.
Git also doesn't prescribe workflows. Overtime, people have come up with standard workflows, but there are too many of them and they all have different mental models. The issue is that most of these workflows are only marginally better/worse than each other and don't necessarily provide additional functionality in any sense. It would be much better if there was only one way of doing things in git. It would make things marginally inconvenient for many, but the marginal loss of productivity would be more than made up by a consistent mental model and the increased reliability of the 'canon' workflow.
Last, and certainly my biggest complaint is the terrible UX and the semantics they convey. It is almost as though the creators went out of their way to have naming schemes at odds with natural language.
I hope someone builds a keras-like tool for git. Interoperable with the tensorflow (v1) that is the git underneath, but exposes a much easier and in most cases feature complete set of abstractions that work for 99% of its users.
For a good example of "user friendly git" I suggest taking a look at mercurial.