It's beyond ugly, it's needlessly incoherent. I use it because I have to and hate it. I've heard people say "the data model is a work of beauty". And I suppose that's true, but why have such a fucked up and confusing set of commands? Doesn't a "brilliant data model" deserve an equally brilliant command line?
The thing that saves git is that it works, and by some miracle, it is popular. People just memorize what they need to do for their workflows and that's mostly fine. Sometimes there's a screw-up and you blow time googling around or looking up fixes.
People won't publicly admit it but a lot of work gets trashed because finagling git intricacies is more painful than throwing away some work and starting over.
Probably because Linus Torvalds wrote it, and also because GitHub was actually quite a significant improvement over SourceForge. I know some people "love to hate" GitHub, but they made some really good "developer-first" UX improvements that many copied for good reasons. And lastly, Linus Torvalds wrote it.
I still maintain that Mercurial is far better for most uses. Every time I mention this I get a flurry of technical replies about stuff most people don't even know about (HN is strongly biased like that, which is not a bad thing, just something to be aware of), but most people just want to commit, push, pull, and some related stuff like that. Git makes a lot of simple common stuff arcane to make the complex stuff easier, whereas mercurial makes the simple common stuff easy and keeps the complex stuff arcane. This strikes me as a much better design philosophy.
Git and Mercurial are a tool designed to facilitate writing code (which is also a tool designed to solve problems). If you need to spend significant time to "get your head around it" then IMHO something, somewhere, has gone wrong.
I still use git because it's just the pragmatical thing to do at this point in time, and to be fair there have been active efforts by the git team to make the common/simple stuff easier in recent times, but yeah, I'm not a fan.
I'd say it was because GitHub created a solid community that worked. And yes, Sourceforge was a huge piece of garbage with it's awful clickbait, misleading "download" buttons, and scammy crapware foisting.
That Torvalds wrote git doesn't automatically make me want to use it, I think most people feel the same.
Named branches don't really exist in git: there's only a moving target name that refers to a leaf node. This means there's no "history" associated to a branch except for the parent commits. But in merge commits with several parents all parents are considered equal, and the system does not contain info about which commit belonged to the "main branch" and which was imported in. This information can be valuable in some cases. This leads to a lot of rebasing just to keep the commit log clean, but this actually rewrites history and destroys information.
Also, there's no support for keeping two parallel views of the same repository (for example, an internal view with lots of subcommits, and a cleaner public view with more detailed messages, and perhaps fewer privacy-compromising names/timestamps).
Finally, handling merge conflicts is still a PITA, especially on LaTeX documents.
I thought that merge commits stored an ordered list of parents, and the first parent is generally the main branch, and second parent is a side branch.
So many times I want to VC a directory but don’t care about commit messages, branching, or other jazz more suited to collaborative work.
With init-lite, all the power of Git is still there - and you can use any commit or command you want, but it’s default would be to simply VC for every file save. In other words, a file save IS a message-less commit.
But if you set that option and run the Assistant, it'll auto-commit files when they change, and can even auto-sync them with other computers, cloud storage, Android devices, etc.
Unfortunately, it required (IIRC) three full time people to administer the server. As for the client (my workstation), it required a proprietary kernel module which would panic about once a week. I'm told our license cost $1m/year (2001 dollars).
Completely agree. I think rebasing is misguided. The objective is to keep history clean and linear. The proper way to solve that problem is with smart log analysis for different customers, not fictionally rewriting the log itself.
$ git help commit | wc -l
506
$ hg help commit | wc -l
59
$ hg help commit -v | wc -l
96
Also, git currently has 169 subcommands by default, vs. mercurial's 50 (more available as extensions though).When you rebase one branch, it doesn't move other branches and tags pointing along the history.
You can't rewrite a repository and change your username in past commits, without completely rewriting all of history, creating two parallel histories, and merge conflicts.
Git's mental model makes "moving a branch onto a different commit" (git branch -f) a natural operation. But no graphical tool I've used allows you to do that on a branch you're not checked out on.
This is trivial in SmartGit, I do it all the time.
Simply drag the branch marker to the commit you want it on. It doesn't matter if it's the checked-out branch or not.
I've tried a few Git GUIs, but SmartGit continues to be my favorite. Pretty much every one of the recipes on https://ohshitgit.com/ is just a simple drag and drop or menu command in SmartGit.
One of my favorite things is the way it handles the reflog. Just click the Recyclable Commits checkbox and every reflog commit becomes visible in the normal log view. You can see the commit's file contents without having to check it out, you can diff two reflog or normal commits, etc.
Don't you think the merge histories of all the repos throughout the globe would be greatly improved if people didn't need to learn the hard way that if your colleague does `push` you need to `fetch`?
> Git is like a chef's knife: extremely powerful tool that's dangerous in untrained hands.
Although, this is all part of the problem with Git. The problem is that it exposes this fine-grained control and knife's edge to the user by default. There isn't some simpler model that people can work with.
I cut my teeth on source-code control with Perforce. Of course, Perforce has many complex features, including stuff like workspaces, which as far as I can tell, Git doesn't have something like that. Anyway, despite its complex feature set, Perforce can be explained in a few minutes. You have some code in the repository. If you want to work on it, you check it out and it gets added to a changelist. If you want exclusive change rights, you can lock it to prevent others. If you want others to see what you're working on, you can shelve your changes without submitting so that they can inspect. When you're done, you submit your changelist. All of this can be done via excellent visual tooling or the command line. I highlighted things with italics because these are the right words for the actions in how Perforce calls them. It's intuitive.
For Git, it isn't that simple. You must first explain a wide swath of concepts. I've explained Git to people, even using the GitHub Desktop app. It is very confusing and intimidating to people, and rightfully so. It confuses me, and I did some pretty advanced things with Perforce (and thus source-code control) before. And there's no default visual tooling. Git also has many names for things that are confusing. Also, Git was invented for a very specific purpose: Linux kernel development. The vast majority of development does not need the same complexity that such a niche development process needs.
When I recently wanted to do something in Git, I just could not figure it out. Probably simple for a Git expert, which is something I am not, but after searching many forum posts, I gave up because every answer was different and caveated in different ways and wasn't working for me. I installed GitKraken and solved my problem in seconds via a single right-click. Maybe I'm an idiot and I don't understand Git that well; both are likely true. But I am able to understand other complex things, so something is amiss. I think the primary issue is that Git requires me to study it just to use it in basic ways. I have an allergy to overly complex things, and so it's just a constant struggle for me. I tend to use visual tools for merging, diffing, managing commits, etc. so that I stay away from the Git CLI, which exposes the complexity in a non-usable way.
Lastly, Git is very narrow minded when it comes to things it controls. It assumes everything should be text.
I need to make more decisions because of its limitations (single repo or one repo per module? Or maybe use submodules somehow? With P4, we had a single repo with all of the code of the entire organization).
Should I rebase or merge? Or squash commits? Should I cherry pick onto a new branch?
If I want to checkout a new branch while I have work in progress, do I commit it and later amend or revert, or do I stash it? Or do I rely on autostash?
Do I push directly to main, or do I rely on pull requests? Should those merge or squash commits?
I understand that all of these options and concepts make sense for distributed orgs, like the Linux kernel dev community and many other opensource projects. But I don't understand why so many traditional organizations are adopting Git. Its model is way too complex for the way normal orgs work (1 centralized server as the source of truth for the whole project), and it has serious limitations for anything which isn't pure code and isn't carefully curated.
From my perspective, these are policy decisions that need to be made by some "management-ish" level. Git provides the mechanism to do all of them. It's up to you/your organization to decide how to work.
In the open source project that I run (20 years, 75+ developers over time, 400-500k LOC) we all have a clear understanding of (e.g.) whether to merge or rebase. On the odd occasions that there's a lack of clarity, it's normally a great sign that it doesn't matter.
The fact the you would be asking those questions suggests to me that the necessary policy-level decisions have not been made (or have not been made clear).
For most unitary organizations, some of the options that git gives you make no sense at all. That doesn't mean git should change, it means that it's not a great tool for unitary organizations.
Note that some of the choices (e.g. stash vs commit) are choices that each dev has to make individually, and some are pure incidental complexity.
`ls` wouldn't be better if I had to pass a flag to see the output as today, and another flag to print one character per line, and another flag to print each character in a different color etc. (even though that would give me 'more freedom').
Part of the problem is that Git, to make it manageable, requires all of these types of concerns and decisions to be addressed, and secondly, it has somehow become the only standard that people have even heard of. There isn't even a decision about which system to use anymore.
Having used both, I still prefer Perforce over Git. And if it were up to me, I would take a step back and investigate other offerings like Plastic SCM. But trying to make these decisions is nearly impossible now that Git is treated as a given.
Also, file locks are awesome if you're working with binary files (a thing that P4, unlike Git, can actually do), or even when doing a big refactoring that you know will cause conflicts with any other change. Otherwise, at least on our server, we very rarely used them (ignoring the temporary lock just as you're submitting code).
I'm not sure what you mean about rebasing. The basic P4 workflow is equivalent to `git pull --rebase`. In fact, it's pretty hard NOT to rebase in P4.
Also, why is your own branch useful actually? Nevermind your own repo? You can always just keep multiple copies of the code if you really want to.
Also, with P4 you don't have to cleanup your whole working set just to switch branch - it's just a `cd` away!
Of course, different strokes for different folks and all that.
Funnily enough I think Atlassian/Bitbucket comes close to a good intro doc to git on their site complete with a visual guide. I still found it inaccessible to people totally new to the basic concepts though.
Stash, pull, stash pop. Done.
(I don't use rebase because I like my history to tell the truth rather than be fictional. Maybe stash is less necessary with rebase; IDK.)
git branch my_stash git commit -am WIP # instead of stash save git pull git cherry-pick -n WIP git branch -D my_stash
You have to remember a second command with its own peculiar syntax and semantics, but don't gain any functionality.
Stash is a superfluous misfeature.
Your alternative, on the other hand, uses an obscure flag to cherry-pick. What scenario would you use that flag for, except this particular one? How is remembering that flag any simpler?
Also, I don’t think your sequence of commands is correct. First, ”git branch” doesn’t switch to the newly created branch, so ”WIP” would be committed on your original branch. Second, the argument to cherry-pick should be a reference to the commit rather than the commit message. I believe a correct version would be:
git switch -c my_stash
git commit -am WIP
git switch -
git pull
git cherry-pick -n my_stash
git branch -D my_stashI'm don't know now, why I suggested the convoluted temporary branch strategy. Probably because I assumed the GP didn't want the WIP commit, but I guess you could just get rid of it with `git reset HEAD^`. Personally I think WIP commits are way better than having uncommitted changes lying around, and what better time to create one than when you're at the terminal pulling and rebasing anyway? Anyhow.
Now when the rebase fails I can just abort it and be in a very easy to understand state: I have a tracking branch that has diverged from the remote, as `git status` would put it. I find this much better than "my tracking branch says 'up-to-date' but only because my actual changes are in a temporary branch somewhere, or heaven forbid, a stash."
> obscure flag to cherry-pick
Sorry, I'm having a little trouble with this one. What flags aren't obscure then? It's one of the elite 0.01% or so of git command-line options deemed worthy of a short option, so I think it stands to reason that it's rather frequently used.
Personally I used it a lot when I first started using git, before I got the hang of amending and squashing. Almost exactly the same way as I used to use stash, before I realized it was adding negative value. :)
Have you never been in the situation where you pop your stash, have a conflict, fix and commit it and then forget to drop the stash? (pop only drops it automatically if there were no conflicts.)
What if you want to save resolving the conflict for later? Do you just leave it in your stash to have to dig for later (amongst all the redundant leftovers from the preceding paragraph)? Or do you remember to run `git stash branch` at this point, and hopefully don't get interrupted before you can do so? Better, IMO, to just use branches in the first place, instead of this weird out-of-band thing where things are kind of like commits, but not really, and live in a separate place I have to remember to check.
Sorry about the length.
Now staging (aka index) is special behind the scenes, making the model more complex for Al users.
I frequently use Git as an interview question, but only when the candidate lists Git among the skill set. Specifically, I ask how does Git figure out when you've renamed a file. If you don't grok it, don't list it.
Why ask such a gotcha question?
How does git figure it out?
That second part is actually important from the user's perspective, not as details on the internals: every single new hire we've gotten who is still learning version control expects svn to detect automatically, and has to be told about "svn mv".
Once you wrap your mind around what commits, heads and remotes are and learn to rebase you get an incredibly simple and fine-grained control. I never use stash because it's trivial to create a WIP commit and rebase later into the chunks I want to ship to permanent history.
Git is like a chef's knife: extremely powerful tool that's dangerous in untrained hands.