I disagree. For example, we have, from “git checkout —help”:
git checkout has two main modes:
1. Switch branches, with git checkout <branch>
2. Restore a different version of a file
The first variant never loses changes you made that aren’t in git yet, the second is explicitly designed to revert them. How does that directly reflects git internals?(And of course, there are many inconsistencies in the CLI that do not have to do with git internals that, even if you know what you want to do internally and which command to use, make figuring out the CLI incantation to do it harder than needed. That’s a different subject, but still contributes to “git is difficult to use”)
Restoring a different version of a specific file/tree, involves recursively restoring wc of those files/trees to match the referenced blobs.
So both are actually primarily the same task. Knowing a little about internals is exactly how it is easy to understand how the same code (and hence the verb "checkout") came to be used for both tasks.
The reason it's still not great UI is that switching branch and restoring file arise in very different circumstances, and I want different guarantees and warnings and confirmations -- so using the same command still only makes sense when thinking very mechanistically.
git commit -am “Changes”
just does not cut it, if you call yourself a professional.The tragedy, if you ask me at least, is rather that they then start imposing the "keep it simple" culture onto everyone else, which frankly turns Git into what SVN and CVS were accomplishing before it, with all the drawbacks of those. This keeps 90% of the team satisfied 90% of the time because there's nothing wrong with strictly linear graphs and the pro's that are asked to produce these, can always squash-merge their intricate local development history before they push to Github (which some Git users also think is part of Git proper).
Something about using Git in the aforementioned way just bugs me strongly. I admit it's a me problem, very likely, but lately I've also had to admit that it's not just that either.
For instance, if I need to fix a bug I use `git blame` to find the commit where I have learned the bug originated. I do a `git checkout -b ... <commit>` to start working on a fix, creating a branch starting at the problematic commit. Already that is head and shoulders above what many people I work with do or know _what_ does (or why would one want to do that).
I do it because it creates a _trail_, certainly more so than just committing on top of `master`, even with a good commit message.
But my practice doesn't produce linear graphs, even as pushed to Github (which we have to use, for better and for worse) and shared with everyone. I then get people coming to me and complaining they can't merge and it becomes obvious they don't understand Git sufficiently to do anything else but `git reset --hard` or worse, `rm -rf * && git pull` and hope for the best.
Not sure where I was going with this, something about why use Git when it's the new SVN with everything SVN had and none of what SVN didn't have...
Setting practices so that linear graph will be easy to understand in history is still a good idea, no? I'm not religious about squash-merge on master but when I look at master's history, I'd expect each individual commit to have a good message and be releasable.
Point being that branches aren't something to avoid, implying that complicated graphs are not to be avoided either, but embraced and knowing how Git works it's not a problem at all (unless your "bush" is accidentally complex in a bad way) -- except that if noone bothers to learn Git, it _becomes_ a problem, solved at the cost of the value that Git provides -- branching (not just ephemeral branching for your local convenience). Exacerbated by Github since everyone pulls from there -- meaning that production-grade code is not a true graph but a linked list, on average.
I think this is the disconnect. I could see big libraries maintaining branches for each major release and I understand why linux does it. But if I'm maintaining FooService at work then I actually do just want a linear graph of all the commits that have been in production, in commit order.
Just saying, in the common case, the simple approach actually is pretty good.
Unless you're saving every keystroke from your editor you're already squashing history, we're just arguing about degrees.
This is because of bisect. Bisecting broken commits doesn't work. Every commit should build.
In either case you should still rebase -i your branch as necessary to make it look clean when standing on its own.
First, I agree commits shouldn't store broken snapshots -- if that's what you mean -- code that doesn't compile or outright is _known_ (as opposed to omissions that weren't caught otherwise and made it into the commit) to be broken, not run, produce runtime/type-checking errors, miss dependencies/assets etc. Not everyone would agree -- in our shop people routinely commit "stuff" for reasons they don't disclose that also remain unexplained to me (not having any explanations my way), and then more stuff on top of that. At some point they tag one of these commits as "v2.0.0" triggering automation that releases a package, often broken. Then they scramble for "v2.0.1" etc. I find all of it tedious and unnecessary -- my best practices would rather be to run automation that does checking and sufficient filtering for "bullshit code" as early as possible -- at the "pre-commit" stage, so only whatever passes through that ends up being committed in the first place. If it yet runs into regressions or other problems in production, I fix (re-triggering all the checking again) and release a strictly patch version -- unless fixing was impossible without breaking compatibility in which case it may be a minor or even a major version bump. I do tag commits, too, obviously. But in principle every commit is "production", the difference is not every commit makes up a _release_ (implying to the general public / intended audience).
Regarding rebasing -- that depends on what you mean exactly -- there's different ways to rebase -- you can squash, auto-squash and/or apply fix-ups, or you can just transplant stuff -- when you say "you should rebase" and "patch on current master", what do you mean? Github-driven projects often don't permit pushing `master` without a PR, so a rebase upfront would have been necessary if the author for some reason is not on a branch [other than `master`].
"Actual merging" -- do you mean merge commits as opposed to fast-forward merging which doesn't produce an additional commit? If the latter, what does "merge from history" mean, again? You just need to produce a working snapshot, expressing it with a commit with N parents, there's no more to it. It's fixing of the merge conflict that requires you to understand the graph, the resulting commit is just the period at the end of a long sentence, so to speak.
Anyway, I really missed the point you were trying to express with your first paragraph, I am sorry. Do elaborate, please.
Bisecting also _benefits_ from non-linear "actual development" graphs -- apart from commits that don't feature broken code committed haphazardly for "reasons" (some people use Git as backup, that I know for a fact) -- since they don't hide the work (one of the reasons I prefer raw graphs over squash-merged "polished" stuff).
One thing I should mention in any case is that I do find slicing work into atomic commits often very tedious and counter to what Git is supposed to sell (distributed friction-free concurrent versioning). Because my brain doesn't always work in terms of concepts aligned with Git's -- I routinely may start with one feature fix, on some branch, then discover N related issues, fix those because they're in front of my face then and there, end up with an unreadable diff I can't cleanly add in chunks, etc. None of that is facilitated by Git in any more capacity than just being a scalpel. I don't always want to cut down a tree with a scalpel, obviously.
Pijul, an alternative VCS, uses this nice patch theory guaranteeing you can "apply" commits in any order, compositing your changes essentially -- a feature is just some baseline that is added N commits (in any order, like the mathematical `+` operator). That way you don't have to rebase anything because parenthood doesn't break merging -- if you fix a bug with a patch in Pijul, you can store it once and count on it being applicable to any snapshot made later, even if the result isn't visible -- unlike with Git where rebasing some old commit will abort and ask you to fix a conflict because Git cannot continue.
Code always lives in a context, and when you're fixing a problem that exists in top-of-main the context of the fix needs to be top-of-main, not some commit way back in history. Also if you do it that way, you'd better hope that no later commit also touches that same line.
> I then get people coming to me and complaining they can't merge
A team needs to agree on git practice in advance, and not have one wildcard go off and do their own thing.
Git sucks on so many points that there ain't be enough walls in the world to write our lamentations about it. But it's damn fast. If I have a doubt, I just create a backup branch before messing with the work at stake, and the bottleneck will be the time I take to type the command.
And I don't know if SVN had some advanced mode to do any branch in local, but in my frightening memories full of scarces, one had to synchronize everything to the central repo to do anything.
The people are confused, it's a fact. So it is confusing. Stop gaslighting people.
I don't think this sort of aggression is warranted, as the fact that I find something confusing doesn't directly imply an intrinsic feature of the object that I'm confused with. One can reach that conclusion by observing that, not everyone who learns about the object finds it equally confusing.
All that to say: "The people are confused" doesn't mean that "All people are confused".
If your product has a reputation to confuse users compared to other products, your product confuses users.
Let's not start to bend reality just to back up some narrative because after reading a N hours documentation everything is OK.
If you expect everything to be as easy as pie without needing to make a little effort to read a bit of documentation, then perhaps the problem is not the product but the fact that you are in the wrong industry, or the wrong role within that industry, for you. Have you considered a management track?
Git is intended to make certain patterns possible, and practical. “Easy for people won't read some documentation” was never one of its design goals.
No one said everything should be easy as pie.
There are other software similar to git that have not such reputation. Version control is not new.
I didn't ask why git was widely used. I didn't say git was useless.
Again, there were version controls before git came out.
Yes, there are alternatives that aren't used by anyone except dedicated fans. If they had the wide user base that git enjoyed you'd hear just as many complaints about them.
Classic strawman.
Is your contention that all reputations are deserved, by definition? That’s certainly an interesting take. It leaves zero room for the concept of an “unfair reputation” for example. Maybe you should rethink your argument here.
I could show you thousands of message backing up the confusion.
But you can keep nitpick irrelevant part of messages and pretend you are very smart.
If you made any other elaborations on why you disagree with the post you were arguing against, we'd have something else to discuss. But right now you're just posting shallow dismissals with fallacious arguments. You can do better.
I'll repeat myself, I can show you thousands of messages point out how git is confusing. I can show you plenty of message saying "I used X it was fine, but I used git and it's cumbersome", please show me the same amount of messages telling "I used git it was fine, but I used XXX and it's cumbersome."
I'm also not claiming git isn't confusing (I've explained that it is, in another post), I'm claiming its reputation is undeserved, in that it's not as confusing as people make it out to be. You seem to reject the notion that such a statement is even valid, claiming that reputations are always deserved. I find that to be bullshit.
It's valid to think "yes it has a reputation for being confusing, but much of it is undeserved". It's not black-and-white.
This is not what is written here:
> Git is not nearly as confusing as people make it out to be. They just never take the few hours it takes to understand it. Which is a sad state of affairs for such an essential tool in the belt of any software engineer.
> just does not cut it, if you call yourself a professional.
Transplant a series of commits onto a different starting point. You can also use git rebase to reorder or combine commits: see INTERACTIVE MODE below for how to do that.
And then later Rebasing interactively means that you have a chance to edit the commits which are rebased. You can reorder the commits, and you can remove them (weeding out bad or otherwise unwanted patches).
Those are obvious IF you know what a commit is and how they relate to each other (a DAG). But most people don’t. Instead, their only knowledge is what they’ve seen the operation do (tutorial or youtube video).Git itself has a glossary[0] of the terms used in the docs.
--------
[1] many (and I'd include myself here) are fine using the basics, perhaps with some less as-simple-as-possible workflows, but might need to scan the docs if they hit a conflict merging two branches that have developed independently for a fair few commits and have overlaps
GP isn’t saying “git isn’t confusing”, they’re saying “git isn’t as confusing as people make it out to be”
The point being, people exaggerate git’s confusingness when discussing it. There’s an element of irrationality here that’s worth bringing up, especially when it comes to comparing it to competing software. Once it has a reputation for being confusing, you’re more likely to be scared of certain workflows, you avoid them, and the problem compounds. Similarly if a VCS has a reputation for being “simple”, people might gravitate to it, learn it first, then parrot conclusions that git is too complicated because they never really gave git a chance in the first place (often they do take the time to read the other VCS’s documentation, and if they would have done the same for git they would have had no problems.)
It doesn’t help that there are so many bad tutorials out there that simply give you what commands to run, and tell you dumb stuff like “just make another clone if you get stuck”, and that makes the problem so much worse, and isn’t git’s fault.
Git is a bit confusing sometimes, but it’s mostly for reasons like “the reset and checkout commands do too much”, and “some low level commands are easy to confuse with high level commands” not because it’s a fundamentally confusing tool.
/r
Git gets easier once you understand branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space
https://softwareengineering.stackexchange.com/questions/2564...
If what you said was true, https://ohshitgit.com/ wouldn't exist.
Once I understood that, as you said, everything clicked into place.
Somehow the "higher level abstractions" that git tries to do makes the things ever so more confusing.
It is always satisfying to rename something, then merge in some work where someone used the old variable name in the meanwhile, and the merge would go through automatically applying the rename!
Then you are doing it wrong. Sadly this is very common.
I got into training people in Git (I now do it for O'Reilly) because I worked with 12 teams that merged _everything_ into sub-branches. The result was that the `git log --oneline` command resulted in screensful of just pipes.
My initial training goal in training was getting my students to understand a rebase to avoid that mess.
> It's not 1:1 at all.
I don't see any mention of "1:1" in the parent.
Maybe?
> The UI of git - for better or worse - directly reflects its internals.
Can't we say that the low level level commands reflect its internal? ...