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.
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 ;)
Not for me. When using Mercurial back in the day I would manually split up commit, usually by copying over sets of files into a clean repo and committing there.
In Git tho the staging area is a lie. It encourages you commit half-truths. What I'd really want is to be able to enter a commit mode where the on-disk and staging area roles are flipped.
I want the stuff on disk to be what I commit, I want the "staging area" to be the changes that I've made that are not yet committed. This way I can pick a set of changes, compile, run tests and commit.
With Mercurial you could sorta do this with stashing I think, but I swore off it after losing changes a few times.
I wish git didn't use the disk at all! It gets in the way of parallelizing work. For instance, I'd love to be able to make a bunch of trial commits, then in parallel verify that none of them breaks the build. Or while a build/test loop is happening on one branch, switch to another to continue working.
https://github.com/tv42/staged does something like that by writing the staged content to a temp dir.
(It has some smarts for Go GOPATH adjusting on top, but might not do things right with modules, at this time.)
Once done delete temp branch and push.
No, I'd say the opposite. The staging area encourages me to think that I can make my change and split it up into logical commits afterwards, even though I know I'll actually just give up and make it a big commit. When I didn't know about the staging area and just committed whenever I could, I produced better, smaller commits.
That sounds like a personal discipline problem and not a poor tool.
Both are guns. Neither will shoot you if you understand how to handle it. One is much easier to make mistakes with than the other.
The parent is saying that Git is the Nambu of DVCS.
https://en.wikipedia.org/wiki/Type_94_Nambu_pistol#Unintenti...
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 is the mental model 99% of newbies will have for something that basically pledges to save and sync each version of your files.
Deviating from the user's mental model will create roadbumps and should not be done without a very strong rationale. Especially not for a feature that's fundamentally optional.
So? When you're saving a file, you're also overwriting its entire contents. Good luck reverting back to the file before you saved it.
There is no automatic model for "this change is worth tracking" and "this change is not important enough to annotate". That's the model that git is enabling, and it has nothing to do with the "save" button in an editor. If anything, it has more to do with the "track changes" feature in Word, but more powerful because it allows you to group multiple edits in the same change.
I don't understand the point you're trying to make; this is just as true of the command I gave.
zfs snapshot pool/home/git@2020-09-07This 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!
Maybe you find it easy because you don't see the subtleties. The answer to reverting the last commit for example can't really be that simple because it depends on what the user really wants to do. Do you want to keep the changes in staging? Reset the index but keep the changes in your working copy? Or reset the files to their state at the previous commit?
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:
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.
"...locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end..."
If you just want to push all branches or tags you should use --all or --tags.
but if you want a system that protects you from these mistakes by making mistakes impossible, then you get a system that is very rigit and actually harder to use.
git protects you from these mistakes by making it possible to recover.
in this particular instance though, there could probably be some extra help to recover. (some way restore the removed refs)
To be fair, one should always look up options you are unfamiliar with before using - and Stack Exchange is not an authoritative source.
--mirror
...Newly created local refs will be pushed to the remote end, locally updated refs will be force updated on the remote end, and deleted refs will be removed from the remote end... [my emphasis.]
On the other hand, if you are on a system where the behavior can be fundamentally altered by multiple configuration options, this will not necessarily help you much.
...This is the default if the configuration option remote.<remote>.mirror is set.
Something like
You are trying to remove commits from twelve branches.
Are you sure that's what you want to do?
Include the --force option to go ahead with this change.
would be a whole lot better.Even if it gives you the tools to undo the mistakes, it saves you time and stress if it keeps you from making the mistakes in the first place.
You're annoyed at them... because they do things that you don't know how to do? How is that their fault?
"In the end git is not in production, it's just a tool to manage code, I'd rather be an expert on the code than the coding tool."
That's a very short-sighted attitude. It's like saying, "I don't want to learn how to operate a bulldozer, because I'd rather be an expert on dirt rather than the tools to move dirt."
Git ends in my production multiple times.
1. In my side project game, auto update and replay system is based on Git. For every update, there will be a commit appended to the code repo which is the most recent update. If a player wants to replay a game in previous version, just checkout the appropriate commit, and run the replay using exact the same code. I'm freed from backward compatibility issue & update subsystem which handles diffing, compression, transporting by a single decision. https://github.com/feisuzhu/thbattle/blob/master/src/autoupd...
2. Another project written by me, which is a monitoring system, distributes it's rules by a git repo. Monitoring agents in the nodes cares about authenticity of distributed rules. So I just sign the tree hash and embed the signature in commit message, which will be later validated by monitoring agents. https://github.com/leancloud/satori/blob/master/satori-rules...
Once you are collaborating, there is simply more to good code than what you our your peers know about the code or the language. Working well and effective with others has a huge impact on you, your peers, the "company" and in the end the product.
Further, I know a lot more about my cars than just how to change the tires. E.g. there are know issues with certain popular car models. Knowing about them does help, not every random mechanic does.
Also, if my car does certain things (surprise, they do all the time, they are complex nowadays) that are easily explainable or even somewhere in the manual, I am not going to ask for help every.single.time. I have stuff to do, be somewhere. I am not going to put my car in the dealership all the time.
Git for me is a productivity tool, in particular when I'm working with others.
You sound like the guy I once collaborated with that didn't want to use git (because why should he learn it now?) and instead sending the whole code via skype every day.
That's exactly what I'd expect someone to do after I commented on their PR.
> That's exactly what I'd expect someone to do after I commented on their PR.
The vast majority of people do not. I certainly wouldn't expect someone to waste time on that.
That's a very bold claim.
It's certainly been the expected workflow everywhere I've worked. You might consider it a waste of time but I'd wager the resulting mess of commits from not doing so wastes far more time in the long run.
An unclean history is less likely to work well with bisect too, as the individual commits may be broken.
You mean when where and how a change was introduced? I dont think bugs are located in the history, since bugs are operational failures on a deployed branch.
1) argue that they really don't need to change anything 2) push more commit(s)
Why would it be better to rewrite history?
It is also a very wholesome and meditative activity.
Most piano players don't have a clue about how to tune their pianos, though.
Most professional musicians know their instrument very well - and still know a man for the "hard" stuff, e.g. for thorough maintenance or repairs that require craftsmanship.
And there are obviously variants. The guys that fix their instruments regularly and experiment with e.g. cooking your stings, and musicians that hand them in for the tiniest, easiest tasks.
So there's little point reading about exotic features upfront other than to know they exist. And which features are exotic depends on your workflow.
It would help if git interface was consistent enough to make remembering this stuff easier.
For example I never remember the exact options for git reset because I'm using it just rarely enough to forget them when I need them again.
I would argue the value is in knowing that something is possible using the `git reset` command so you know to go looking for the exact option to do what you want. And more likely you'll remember the operation if it's one you find yourself using frequently.
-- someone or someone else. I forgot.
And as a side bonus it will probably make you a better coder.
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.
One of the reasons that we able to achieve so much with computers is that there is a separation of concerns between different areas.
Requiring everyone to fully understand git is like requiring people who code in high-level languages to understand and apply chip design in their day-to-day work.
Imagine if when you tested some Python or Java code you got an error from your CPU and needed to take it out and debug it with an electron microscope.
Contemporary git has this disease. Its (command line) user interface is a mess. I could say more about what you would do to make a better version but a comment isn't the place for that.
The defence that you are using - that smart people should be able to learn git fully - is like saying that any and every smart programmer should learn IC design and buy their own electron microscope, and that's why it's OK that the chips keep breaking.
1) It's like understanding the basics of databases, network protocols, or compilers. It gives a lot of insight to how things work in a pretty deep and generalizable way. How do you organize data, and why are DAGs, Merkle trees, and hashes awesome? It's a beautiful case study in data engineering.
2) It's like knowing the shortcuts in your editor. It makes you more productive. If a programmer is hunt-and-pecking to type, and gets confused by shortcut keys, they'll be less productive.
Yes, I understand not all programmers will know how important it is to know this stuff, and I won't disadvantage someone who hasn't done this YET in hiring. But I would never hire the type of programmer who says "I don't need to know this." You do.
I'm sorry, but it takes a couple weekends of work to write yourself a git end-to-end from scratch. That's 0.5% of the time you put into a CS degree. If you don't have the interest, discipline, or drive to do that, there are plenty of jobs out there.
git internals are simple, but hard. Like Go. If you don't understand them, the userspace is a near-infinite pile or arcane complexity, incantations, half of which break something in counter-intuitive ways. If you do, it's a matter looking up the right command in the docs in a few minutes.
Yes, compilers, database, and other tools abstract away a lot of stuff. But if you don't understand the internals, you're likely to hurt yourself and my system in very bad ways. I don't want that on my team. My experience is good programmers are fluent one or two abstractions up and down, to not e.g. make a database query that does a full table walk, run out of stack space with a compiler that doesn't do tail recursion (and conversely, know they can use tail recursion with ones that do), etc. A tool you use every day definitely falls into the category of Stuff You Ought to Know, in a way that understanding how quantum tunneling is used in an SSD is in the category of Stuff You Don't Need to Know.
If you're hurting yourself with git, that's a good signal it's in the Stuff to Know category. And if you've wasted more than a few hours fighting git, as it sounds you have, it sounds like making a focused effort to learn it will save you time in the long term. Probably in a few months, even.
I use an SSD every day though, as well as an LCD display and a laser in my mouse. So by this reasoning, I need to study quantum mechanics; it would only take a few weekends of focused study to understand the Schrodinger Equation etc.
These things fall into the "Don't need to know" category because we as a species have made very effective user interfaces to them whereby you really need to know almost nothing about their internals to use them.
The ideal version control system would work like a mouse or a monitor. Completely intuitive, just works™.
As a footnote, I would expect you to be able to understand things like SSD performance and reliability, and how it's affected by complex algorithms in the drive controller (e.g. wear leveling, garbage collection, write block size, etc.). I would also expect you to be able to understand things like how subpixel rendering works, how rendering engines coordinate within LCD refresh, or how displays advertise their parameters to computers.
You shouldn't take those as black boxes either. You do get into bugs and issues which relate there, and an experienced software engineer will have a depth of knowledge around oddball topics like that. That brings huge value.
It sounds like you're not a nerd. Why did you go into software engineering? It sounds like you're not interested in the stuff. There are lots of career tracks which don't expect people to do those sorts of deep dives, and where willful ignorance is okay. Engineering, including software engineering, just doesn't happen to be one of them. All the good software engineers I know will do dives into this stuff, and that expertise accumulates over time.
The key thing is most of us enjoy those deep dives. That's what makes the career track a good fit.
If you don't, you'll be doing the equivalent of maintaining a COBOL database on a mainframe as you get older.
For my engineers, I'm not looking for tools which are "Completely intuitive, just works™." That's Scratch. I'd advise you to code in Scratch if that's what you want. I want tools which enable people to be productive, efficient, and get stuff done at a high level of quality. If that has a learning curve, that's okay. People are coding 40 hours per week. If my programmers spend a month learning each year, and that makes them 50% more productive, they'll beat your Scratch team. That's why good programmers get paid the big bucks, and mediocre programmers can't find jobs.
There are two separate issue here though.
(A) How much work does a given person want to put in
(B) How much work does a given tool require.
It can simultaneously be the case that git is bad/overcomplicated AND that you should only hire people who bother to learn it really well.
Why?
Well, learning hard things is a reliable signal of diligence and hard work, which are generally useful traits.
But at the same time, forcing everyone to learn something annoying and time-consuming just as a test of grit isn't maximally efficient. The same effort could be put into more productive tasks.
> Why did you go into software engineering?
Well, I'm not a software engineer - in the Data/ML area so I am much more interested in the properties of data than the properties of code. But having said that I certainly like clean, efficient code and I care about languages (maybe just spoiled by python?!).
I can't see myself as a software engineer so I think your instinct is right. My passion is data and ML.
For a data/ML position, in most cases, I'd expect you to be able to handle data cleanly and efficiently.
If you can't, there are jobs far over on the data side, but:
1) As a business data analyst, you're fine with Excel and PPT, but you'll be paid roughly 1/3 of an ML/SWE position, and you should have excellent communication skills.
2) There are primary mathematical positions, where you work with a data engineer, but you'd better be awesome at math. AND it still helps to be able to handle data cleanly.
Even so, good data workflows require knowing what you did, when, and to which version of data. Properly used, git provides an archival log of some of that. I use very similar data structures when I build some of my own data pipelines too, with data stored under its hashes, Merkle trees, DAGs, and similar. If you find that "annoying and time-consuming," I'd hire you for a business data analyst, and not much more.
It sounds like you find that stuff boring, though. It's a test of interest, passion, and drive, much more so than diligence and grit. Although those are important too.
Merkle trees are also fun and have applications elsewhere like cryptocurrency/blockchain.
I don't have a problem with computer science in general, it's a fascinating subject.
I'd be very interested because it's rare for me to see anyone attempt and, when I do, they break a basic use case.
Insanely complicated commands to undo things are one symptom of this.
As a user, you want to "save" some code and you also want to "share" it with others. You also want a historical record of what you did.
But obviously you will occasionally save and share things you didn't mean to. Like your Python virtual environment, like a bunch of pictures in their binary format, etc.
A sane version control would provide a point-and-click way to make these disappear from history (though with adequate security protections to make sure that only authorized people can do it).
If I'm a user and I want to save, I do it with my text editor. If I want to share, I can do it with Github, Gerrit, Gitlab, email, pigeon.
I never email people things I didn't mean to and, if I did, I wouldn't expect my email software to let me delete it. The centralised services allow it to some degree but even they don't allow information to be un-disseminated.
VCS is necessary to deal with changes that overlap and conflict. It's not for backup and it's not a method of communication. If all you need to do is save and share, you don't need VCS.
So nothing is really gained but not allowing this, but it makes git very user-hostile because mistakes cannot easily be undone.
By removing it's decentralised nature you've fundamentally built a different VCS. Perhaps SVN is acceptable for your use case, that's great! It's definitely not git though - basic expected use cases were lost as predicted at the start of this thread.
The core task of a VCS is versioning and collaborating on text of some kind. Git doesn't do this in an optimal way, so eventually it will get replaced by something better. In the meantime we'll all get on with learning its ins and outs, just like previous generations learned how to use punchcards.
git rebase -i {hash before your changes}
git push -f
And since you talked about point and click, you could easily enough use github permissions on branches to prevent this on protected branches or you could configure your git repo to disallow force pushes. To get specific branch protections on a normal git repo you would need to use a hook to validate the update before it's accepted.For example, suppose I init a new repo and accidentally commit my entire virtual environment, then push, then do some real work, push a few times more and then a colleague notices (after they have pulled, worked on and pushed) that the venv stuff is there.
In an ideal VCS, you would have a simple command like git purge /badfolder that would make it as if it never existed.
But AFAIK that doesn't exist, or at least the ways to accomplish that are pretty gnarly and dangerous.
Second, I would tell you that git has a command for just your situation.
git filter-branch
https://git-scm.com/docs/git-filter-branchYou can run a command against every commit and it will then recommit. That would let you remove, for instance, an entire subdirectory. The downside here being that you are rewriting history on something you've shared with the world and that has larger potentials for causing issues with contributors.
I guess my point is really this, git is simply one of the many tools you likely have to use on a daily basis. If you have to use a tool in your daily job it's in your interest to really grok the various ways your tool can be used. You'll want to really understand the primary use cases in detail and the less used ones you'll want to know in passing at least. That allows you to realize that something is possible with the tool, even if you don't recall the exact specifics. A machinist would have the Machinery's Handbook, a programmer will have multiple internet references. Maybe the real point is that it's _ok_ to not know the exact syntax and need to reference it for more esoteric operations.
Git demanding a large chuck of user mindspace isn't an advantage for git, it's a signal that git is bad and needs replacing.
You aren't writing x86 assembler. You are presumably writing some other, higher-level language. I would fully expect you to know that language in detail and even better to understand the performance implications of the choices you make in that language. Knowing the lower level details helps there, but it's not 100% required.
With git, it's something you _directly_ interact with so I would expect you to understand it in great detail.
Yes, you are describing what is broken about git: its abstractions are leaking too much so people who touch it have to know all its internals.
I touch x86 assembler every time I run high-level code, it's just that other kind folks have gone to a lot of effort to make it so that I don't have know how the internals of that low-level stuff work.
Abstractions allow people to be productive without knowing in great detail how absolutely everything in the universe works. A good tool has simple, non-leaky abstractions with a simple interface. Git is not a good tool.
The ideal option for each of these things is that it "just works". When you have to think about the internals of your package manager or your CI or your virtual environment, that's a flaw in it, not a reason to celebrate.
I picked Debian over Red Hat since, at the time, I could understand how .deb packages worked, and look over the state of the system. Red Hat had more opaque internals. If something broke on a Debian system, rare as it was, I could go in and fix it manually. If something broke on a Red Hat system, it was generally in a binary database file, and meant a reinstall. Red Hat also broke more often, I think for very similar reasons in design philosophy.
If I were making a tool for grandma to manage her photos, that's be something different. If you're making a coding tool for 3rd graders, perhaps you want to hide more stuff too, but even there, many modern coding environments translate blockly into Python/JS/etc. code, and show the code to kids so they can see under the hood.
I have a car, and as a car user, I want thinks to just work. As a car mechanic, I'd like things to be understandable, fixable, documented, and transparent.
git is like that. It has simple internals. Once you understand them, the userspace become very understandable too. The upsides of the elegant internals far outweigh the downside of a slightly clumsy userspace, which is why it's the dominant VCS right now.
It took over precisely from things which "just worked" with a simple userspace, and clumsy internals, like SVN and CVS.
I use PyCharm. I don't know how PyCharm works internally. I don't even know what language it is written in. I know that it provides syntax highlighting, smart replace, code completion, etc.
Similarly, my car mechanic has a bunch of tools that he doesn't understand in detail; they have interfaces (like a gauge on a pressure sensor).
Progress requires these interfaces, it requires these abstractions, and over time I'm pretty confident that we'll get a better VCS than git that has better, more user-friendly abstractions and it will take over the market.
Besides, nobody is arguing git needs to be made weaker, just that it would be nice if it had a more gradual learning curve. Easy things easy, hard things possible. If you can’t see how git is hard you’ve forgotten what it is like to be a beginner.
Software development is hard. That's why we have to spend years studying it and earn conspicuously good wages.
A basic project doesn't need git anyway.
Agree on the need for education to be a good developer though.
We have the whole education system to deal with that. It's the same problem as in mechanics, chemistry, biology, etc.
If you intuitively grok how git works, that’s great. I’m going to guess you probably don’t really use it in any challenging or new situations and are just comfortable with your particular workflow. But maybe you do have that mastery level over this one tool in your code management system.
But guess what, other folks, true genius folks, either can’t or don’t have the mental bandwidth to learn every nook and cranny of this tool. If you don’t recognize that, you are willfully dismissing a lot of really smart people because their brains don’t work the same way yours does. But when you do that you are weakening yourself and your own capabilities.
So step back and re-assess your take here. It’s wrong, and it’s toxic to your own outlook as well as those around you.
I don't hugely feel like seeing things from your point of view because the only thing you've really told me that might change my mind is that you lose people when you require a basic amount of capability. I'm sorry to hear that this grievously wounds you on an emotional level, but I don't see that as a loss.
Saying "basic competence" is horrifically abusing language here. Git is a glorified save/share/undo tool, demanding people spend several days reading the manual is an absolute caricature and yet you're seriously saying that.
The reason people are mad at you is that people have lived experience of the interface sucking and failing to do the job an interface does - convey via context what it does and you're basically blaming them for wanting to fix the problem they've experienced instead of sucking it up and Being A Real Man and solving problems they don't have as a workaround for the tool failing to solve problems they do have.
And it's not like Git's interface problems are subtle. It's an absolute joke, and you're not even claiming it's an acceptable interface so much as rejecting the entire concept of user interfaces at all. I'm not sure how to explain how utterly infuriating that is.
You're saying "you're doing it wrong, so I don't care" while simultaneously complaining that some of the solutions could hurt other peoples' use-cases.
What is the correct response here? Reject their own memories and emotions and yield to your blame, or call you a willfully-oblivious fuckhead?
All that being said, this is not a reason to then take the next step and claim that basic competence in what is today an essential tool is optional. It is necessary and to work well you must know it well, otherwise the frustration you point out will be part of your life every day. As opposed to something that you live through and say goodbye to.
The fact that everyone is taking this as toxic or willfully oblivious is as far as I'm concerned infantile. It has nothing to do with "being a real man" (whatever that means to you), it has something to do with having the maturity to realise that you are making your own problems.
That is not to say we cannot build a better tool. Perhaps we can! Up until this point I have not seen it done without losing something else in turn.
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.
Her problem is she gets discouraged halfway through and never gets to use the stuff she learned.
My problem is I got good at winging it and looking up stuff as needed so I never learn the stuff I didn't needed even when it could be useful if I knew about it.
Probably some compromise would be the best - start with what you need and force yourself to go deep into one random topic each month.
> I remember dealing with folks that would spend three days, writing CLI tools that saved, maybe two hours, over the course of a year.
My friend is like that, but I learnt to aprecciate this when I worked with him. The script maybe only saved 1 minute of work 10 times a year, but more importantly it's self-checking documentation of how we are doing stuff we rarely do.
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
And to give yourself a sense of the commit graph, these aliases come in handy
[alias]
lol = log --graph --decorate --pretty=oneline --abbrev-commit
lola = log --graph --date=short --pretty=format:'%C(auto)%h %C(dim)%ad%C(auto)%d %s' --all
The only 'advanced' thing I commonly do is `git rebase -i` to squash a bunch of WIP commits. And a shell script I have to turn merged branch into a tag, and remove the branch.The other day I had to remove a sensitive file that accidentally got checked into the repo for a couple of commits behind HEAD, and was glad that git had the power to do this in one line and without fuss. (Edit: but yes, I had to look it up on SE)
I've honestly ever felt the need, or had the requirement, to look at the graph.
Same goes I think for `git restore` over `git reset`.
Most people can get going with those 99% commands quite quickly, the problem with git is any move from the known path creates some pretty amazingly complicated scenarios.
And those '1% of the time' commands blow up into time-consuming rabbit holes of complexity. Often, Stack Exchange has several answers for the same question, highlighting just how much inherent complexity there is in the product.
Managing software versions across repo can be a very, very complicated problem. Git provides you with a pile of tools to do 'almost anything'.
A 'well designed product' would make the toolsets and concepts focus heavily on the 'main operations' and then have clear, clean rational idioms, practices and tools for the odd cases, and 'dangerous cases' wouldn't be allowed without some kind of special command.
They have the 'Golden Rule of Git' which is to not rebase on a public branch - this is an excellent example of poor product design. There should be no 'golden rule' that developers have to understand - it shouldn't be possible (without special admin commands). If branches are named/tagged and managed properly, the system would be smart enough to let you know you can't do that, and why.
Administrators exist for a reason, 'sudo' exists for a reason etc.
People who love powerful things, and have an inclination towards complexity seem to love git, people who have a product orientation see it differently.
Already that's a little bit complicated though.
Even though yes, this use case probably does exist, it might be a tricky thing to unwind for some people - what would they do when they have already changed the history of 'their' public branch (?) is something they'd have to carefully think about.
It comes with the territory. We're dealing with tools borne into world where they are, more and more, expected to be suitable for any purpose. Tough mandate, and not the tools fault.
One day git will be supplanted with something that has a different set of issues. Progress.
You can add to them and refactor patch series that are on them, equally valid in the eyes of git.
For example a development branch has no implied "promise" about stability of its history, it is much better to not only refactor the code but also refactor the history so sub-patches are squashed into the single feature patch that they logically belong to, and not spawn lives of their own. There is no reason to run that kind of development branch like a stable "branch of record".
And yet people do it all the time.
The 'rule' is easy enough to understand.
But it's not always clear 'why' that is (in many cases, it won't matter), or when exactly it applies.
In the lowest common denominator cases, the rule is not so hard to follow, but it can get messy quickly and there are many ways to break the rule.
Every single developer I work with (or have in the last 8 years) does this. "Messes up the history" ? The merge commit describes that there are uptaken changes from the "main" branch. It doesn't seem to be a problem in practice.
When we release to production, develop gets merged to master.
We consider a 'feature' a large piece of work that will take several weeks, during which time several releases to production may be done for other work/tickets.
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.
select ... as of timestamp;
> In your list of shout commands I don't see anything that could be used for merging?I'm not arguing for using SQL as a git interface, I'm just saying git would greatly benefit from better interface based on some consistent and clear separation of concerns.
> the problems it is trying to solve are more complex than what could be dealt with in a SQL dialect.
It's not. SQL simplified A LOT of underlying details. There are dozens of types of indexes. There's partitioning and sharding. There's online backups. There are transactions - local and distributed ones. There's savepoints and rollbacks.
If SQL databases were like GIT - selects with joins using different indexes would have different syntax because "you need to understand the underlying structure" :)
Based on how SQL and C/C++ faired in these kinds of processes we could have a standard abstraction layer in perhaps 10-15 years ...
There is at least one database that exists which does support a Git-like DAG for transaction-time temporality: https://terminusdb.com/
It should also be pointed out that "temporal databases" usually offer a lot more besides a linear transaction-time history. Although I've not seen anything that offers a DAG for valid-time histories yet :)
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?
I use both. More complicated stuff I usually do from the command line because I do them rarely enough, and I change IDEs often enough - that I just don't know how to do them in IDEs.
I used git regularly for last 6 years and in that time I've been using eclipse, netbeans, kdevelop, qtcreator, visual studio and intelliJ. And a few fringe IDEs as one-offs. I would have to remember 7 different paths in nested context menus for everything. I believe it's not "unstage" but "rollback" in IntelliJ, but I would have to check that in documentation before I do it anyway.
> Is it even possible to selectively unstage or reset only a part of a file without a GUI?
Sure - it's even faster than in gui, because you do it with keyboard only. I just can't remember the exact options.
And you don't have to remember the menus because they are contextual. Select a portion of text: unstage selected lines, reset selected lines, etc. Select a commit: checkout, create tag, revert, etc.
Things that are complicated on the CLI become routine and that changes the way you work.
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.
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.
My explanation would be:
Git won because it was used for Linux and because it was fastest where it mattered.
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.
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."
Every carpenter I know knows how to change the blade, tighten the arbor, check the fence, adjust riving knives, clean away the dust, tension the belts (if applicable) and maybe even change the motor. And there isn't much more to a table saw.
Getting back to Git, I agree with your sentiment "Within Git, there is a much smaller and clearer CVS struggling to get out.". Most of us should strive to stay within the set of simple git operations.
However, then there's all the other corner cases that are sometimes applicable. Such as clearing away your accidentally published private keys using `git filter-branch`. Most of us will never need this, but it's there for a reason.
But if one groks the "DAG of commits" concept behind git, you can understand what filter-branch does and why and how. It's not a very complex concept.
Again, I won't defend the inconsistent user interface. It could be better. But even that can be understood when needed by looking at the documentation as long as the concept is clear.
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...
The deeper explanation doesn't mean more complex system.
Simple.
git restore filename
edit: on second thought no it's really not very coherent. If you exclude <files> it means checkout all files if you write a <branch>, but no files if you write no <branch>. So excluding <branch> doesn't consistently do the same as using <current branch>. I guess git does kind of suck.
I can use git all right but the fact that I need about 20 different commands to do my job, 95% of them with extra parameters and almost all of them with names that don't reflect what I want to do from a functional point of view is utterly dumb. Again, functional! not technical! The UI should reflect end user functionality, not internal technical details.