It's not really new anymore, but still way underused, so it could certainly do with more attention. Git's UI has become better, but they can't really remove the old UI and tutorials using those, so people keep sticking to that.
We're commenting on one :) But really there's not much to it - `git checkout` is the main wart of Git's UI given how overloaded it is, and with `git switch` and `git restore`, you'll have banned out pretty much all of its regular use. And given how much more straightforward (i.e. they have more guessable arguments) those are, there's not as much need for tutorials anymore.
I can't reasonably start using such functionality until the PC with the oldest software that I still use has updated or I will have to deal with 2 ways of doing things all the time.
Currently, that's an ubuntu 18.04 machine at work and that doesn't have `git restore`, yet.
These new commands make a lot more sense, but the weird thing is they don’t bring anything else to the table.
They behave exactly like the existing ones, so much that anyone that really cared could have just aliased them.
So is there any incentive to switch for the people who went through the trauma of burning the old ones in their soul ? (I often heard that knowing how it works internally makes git commands feel natural. I was lied to)
They don't behave exactly like the old ones, because they do less - which means it's harder to accidentally do the wrong thing, and it's easier to guess what its arguments do.
If you know the old ones already and don't make mistakes, it's fine not to use these, really. I consciously got the new commands into my muscle memory in case I'm pair programming or someone less familiar with Git is looking along.
And yeah, knowing how Git works makes it a lot easier to understand, but it doesn't make the commands more natural. (Except perhaps knowing when you can use a commit id instead of a branch name.)
I had git-checkout syntax burned into my soul. I switched to switch/restore a year or so ago and am happy to be mostly unburdened of git-checkout. I say mostly because I still use it in scripts so they work with old git versions.
You don't need -- as much in the "git restore" example. With git checkout it may be necessary to separate the branch and the paths with "--" but since "git restore" does not take a branch (except with -s), doing this is totally fine
Not typing it with "checkout" gets in the way of good tab completion. At work we have at least tens of thousands of branches and if I hit tab after "git checkout file_path_prefix", my shell is going to freeze for a while, while tab completion is going over remote branches.
How do you end up with that many branches? It sounds like you keep every feature branch around forever. Keeping one around for a few months I get (although personally the sooner they're gone after rebasing or cherry-picking them the better), but this sounds like a full on history of every branch ever.
If someone pushed a branch to remote, then there is a chance that they made a CI build for a customer based on that branch. Later you may need that branch to look at the source code, when you get a coredump, or logs or something.
(Every non-official build is made from a separate branch.)
Deployed versions that need to be referred to later usually get git tagged, but those are not that much different from branches of course (they'll both show up in autocomplete as a committish object). But even then; tens of thousands of tags/branches? At that point it might be worth considering simply baking in the git commit hash into the build artefact for future reference instead of tagging every CI build with a branch/tag.
When I say "non-official", I say that it has some commits that aren't on the main branch. You need to push them somewhere, or else they're going to be lost.
You may not have much choice in the matter, but this level of complexity is where I would strongly recommend a (slightly) more complex architecture.
It's apparently a business requirement to keep every branch around forever, and I'll just take your word for that. At that point, you can have an `origin` remote where work happens, and the CI can include a push to an `archive` remote which is append-only.
Lets you have a development environment where the existence of a branch on origin means that it's in-play, and everything exists on archive if it proves needful.
From the article, I was thinking that it was again a stupid confusing design for the cli to requires the -- even with a dedicated command.
One main issue with git is to not be consistent and logic with the comments. Always to use different way or option abbreviation for different command.
For example having a space or a slash between repo and a branch in a command.
-- is typically to end argument processing and to treat all further ones as files. With git-restore, it's probably only relevant if you happen to have files in your repo that begin with hyphens. A fairly unusual situation, granted, but not forbidden.
Still does not really make sense. Because you can still quote the - if ever you had such a file, and most Unix tools have the -- optional only if you would need it. Not systematic!
> For example having a space or a slash between repo and a branch in a command.
Actually, this one makes sense, once you understand the underlying model of how git works with remote repositories, which (imo) is fairly fundamental to a distributed VCS.
They're different arguments (in your words, having a space) when you're accessing remote repositories and have to specify the location it should access. You can always substitute an URL for a repo in this case, and they fail if you cannot connect to the remote repository.
In all other cases (having a slash), you're referencing a ref in your local repository. This is a local copy of the remote repository. That means that it always works offline, but also that it doesn't sync with the remote repository. You can also substitute another ref, such as a "local" branch.
I wish git had some tree transversal related commands instead of all the crypto commands that nobody understand what they are doing without long tutorials. Got a feeling that this is a case where going down to the metal is better than all the abstractions.
If you want to learn Git from the inside out, I wrote a two-parter that aims to explain Git from the inside out, focusing on the data-structure Git uses:
Finally, _if_ you have an O'Reilly subscription, I am currently writing Head First Git (first four chapters are in early release). If you are not familiar with the Head First series, its a rather unique format that involves using lot of pictures to explain ideas and traditionally the books move a lot slower than most technical books. Ideas/concepts are cemented using puzzles, quizzes, crosswords.
I used to know lot of terminal commands but I'm seriously falling behind due to jetbrains integration which covers 99% of my daily use case. Together with local history, I've never "lost" work in years.
Never heard of switch /restore and will probably forget about it the next time I'm on the terminal.
Rebase and interactive Rebase is so well integrated for my use cases and I feel much more productive without having to switch context.
Reflog and bisect are when I nowadays switch to the terminal, have not discovered an equivalent last time I checked.
I currently use a third-party git GUI (GitKraken atm) but I also use jetbrains products, am I missing out by not using the integrated git functionality? If so, is there a tutorial or guide you could recommend, or is it all fairly self-explanatory?
Jetbrains Git integration is quite self-explanatory - if you're already using GitKraken, you're not missing out much except being able to do it from your IDE instead of another tool. Maybe conflicts are a tad easier due to same syntax highlighting style and ability to edit on the go.
The Jetbrains git interface is really quite good. For me the magic is the general combination of git and local history. The search is good and the diffing and jump-to-source from those. The changelist handling is pretty good too.
I think a quick skim of the available features in the docs would probably give a good overview. Then poking around.
> but I'm seriously falling behind due to jetbrains integration
This IntelliJ integration is the source of quite a lot of git problems in teams I worked with.
I'm quite flabbergasted by this - devs claim to know git on their CV, come in and know what "commit" is and how to use the IntelliJ UI, but don't even understand what its doing. And everyone is acting like it's OK and learning git is a "hard thing ill never need" and we should all use sourcetree or jetbrains. Or people just get so used to it and never understand what exists below it. They lose all sense of what they're doing and just think "the machine knows what I want". Then a vaguely questioned dialog appears - or something similar - and they cause clusterfuck upon their branch - or sometimes even other people's remote branches.
How do we allow our culture to be so lazy that people resist using one of the basic tools because "oh its hard I gotta remember 5 commands" and we find it OK?
No wonder the plane is burning.
It's good that you still know that reflog exists, because a lot of "inteliij is my git client" users don't even know about it. Tho I'm still wondering, isn't it faster/easier to open intelliJ terminal and type a command or two than having to ope a whole new window and click around it?
(also sorry if this sounds like an attack on you, it isn't! just really wondering!)
Also, re: OP: So basically 2 new commands were added that do what other commands already do, but people dont read the docs so we should add new commands so maybe people will read the docs for them?
I think you're approaching git and software dev from a bottom up perspective. You learn the tools, understand why they exist, and then use the tools to solve higher level problems. Unfortunately due to time constraints, interest levels, and simply ease people go top down. They need to switch branch, so they will follow the least effort principle and use a UI. Barely understanding many fundamental tools is common these days for devs, and I honestly think that it's a sign that our field has grown massively in terms of the tools we need to use, the processes we use to deploy, and the products we use to develop.
I have to deliver products and deliverables, when and what do I focus on wrt gaps in my knowledge? Git? Unix commands? OWASP Security principles? Cache busting? global state management? ORM integrations with popular DBs? Kubernetes configs?
It's hard to see the gaps someone else has, and wonder why they can't know what you know, but they may have some deep knowledge in a domain you are only superficially knowledgable in.
I agree we need to nail the basics, but this isn't 2002 anymore, and we don't ship Gold CDs to customers by running a build command on a single PC in the office. Our jobs are so much more complex and multi-faceted, and the oldbeard assumption that things are 'bare essentials' is eroded by the pragmatic realisation that we only have so many hours in the day.
> I think you're approaching git and software dev from a bottom up perspective. You learn the tools, understand why they exist, and then use the tools to solve higher level problems
Actually, I'm trying to look at it more from a "shallow sea" perspective - you have a problem and are given a tool to solve it.
But do you not dive in just a bit to see "hey what is this tool" after you solve the problem?
Or after using it for a while?
UI is also something you have to learn how to use.
Sourcetree UI is as complicated as terminal for someone who never used it.
>I have to deliver products and deliverables, when and what do I focus on wrt gaps in my knowledge? Git? Unix commands? OWASP Security principles? Cache busting? global state management? ORM integrations with popular DBs? Kubernetes configs?
With that mentality, what do you ever learn?
Do you just keep on chugging year after year with "duct-tape the tools"?
Where is the joy in that?
Where is the growth?
Are you always in a rush to deliver software without a moment to think?
You learn about the level you're using - like, are you using git daily?
Just reading a tutorial or two and spending 5 mins a day with it in the terminal is going to do wonders for understanding it long-term.
>Barely understanding many fundamental tools is common these days for devs
It's common for someone starting to develop or starting to use a tool - hell, 8 years ago I have been as confused as "wtf is this git" as anyone.
Gradle was magic to me. Terminal was a dark and scary place.
That doesn't mean that it is okay to stay at that level.
If we accept "not trying to understand" as the new common, then we accept failure and ignorance as the new common.
We accept the world of broken software because people don't understand what they're doing
- and we're telling them "you don't need to understand so don't even bother".
And hell, maybe that's gatekeeping, but fuck it, I'll rather be St. Peter at the gates than accept a world where learning and understanding is something "we don't have time for".
>>I have to deliver products and deliverables, when and what do I focus on wrt gaps in my knowledge? Git? Unix commands? OWASP Security principles? Cache busting? global state management? ORM integrations with popular DBs? Kubernetes configs?
> With that mentality, what do you ever learn?
The way I understand it, this comment is saying you have to prioritize and work on the highest-impact areas. Of course you grow, but until a certain point you don't benefit much from knowing the guts of git more than Framework X.
I have never experienced any joy of creativity from using git, so it's not something I'm putting high on my list. Heck, learning Rust was 10x as good for my development as git, so I don't regret prioritizing that way.
I expect (hope?) that most people understand the git they use in their daily workflow... but that doesn't mean they have to have mastered every dark corner. Find a specialist (Stack Overflow :) when an unusual situation arises. If it's happening consistently, then I agree some more learning should occur.
You can use top-down knowledge to inform yourself on what concepts you need to learn, and you can ignore the parts of the domain you need right now. But you still have to learn them bottom up. Getting confused by the concepts you're using is a gigantic waste of time.
And the harder the concepts, the easier it is to get confused, so there's no trade-off.
How do we allow our culture to be so lazy that people resist using one of the basic tools because "oh its hard I gotta remember 5 commands" and we find it OK? No wonder the plane is burning.
Its probably a rhetorical question but I think its worth answering anyway.
Experienced developers had the luxury of learning git, say, over a 10 year period. I certainly know a lot more git than 10 years ago.
If you are a new developer thrown into your first real project and Intellij handles git for you so that you can concentrate on being productive then learning command line git takes a back seat.
I see this in many aspects of programming. One thing I am struggling with currently, is that JHipster generates applications in a user friendly way. JHipster is highly productive and seems like the future of programming BUT it means that there will be a generation of programmers that do not understand the MB of Spring Java code that is casually puked out by the code generator.
Its depressing to say it, but I think not understanding the tools is only natural and is probably the new normal in this age of complexity.
>Experienced developers had the luxury of learning git, say, over a 10 year period. I certainly know a lot more git than 10 years ago.
The depressing thing is I'm not talking just about off-the-shelf newbies, I'm also talking about experienced devs.
>Its depressing to say it, but I think not understanding the tools is only natural and is probably the new normal in this age of complexity.
Yes, unfortunately, this is becoming the new normal.
But what is the next "new normal" after this? More complexity and obscurity? How long can we keep building that house of cards before it collapses upon us?
the solution I believe would be to focus on creating simpler tools, and by that I mean tools with at least the same usefulness/as powerful as the ones we have now, but with much less cognitive burden, with better interoperability and composability by using simple standard data interchange formats.
If you really believe this, then I don't believe that you understand what the job of a powerful revision control system is.
The "cognitive burden" of git comes as much from the tasks that it is occasionally required to make possible than anything else.
If the only git commands you ever use are push, pull, commit and checkout then its a very simple system with very little cognitive burden. But one day, you may need to perform a truly complex task with git that a simpler system with much less cognitive burden would just not allow.
I do not understand how "data interchange formats" are an issue here. What do you want to inter-operate with?
I generally agree with you that much of git's conceptual complexity is irreducible if you want to retain git's power. But there's plenty of examples of poor-quality and inconsistent porcelain that provide no extra power. Indeed, these "UI smells" mostly offer no benefit at all.
Note that we're specifically discussing the theoretical reason for git's usability woes. The costs of actually fixing them in git aren't trivial, of course.
I don’t know about most people but i have to relearn stuff if I don’t use it.
I use the basic git commands a lot but the wider set not very often.
So maybe I should learn Git from first principles every year? Like a cop would practice at the firing range?
But I’m doing that on my own time. But then what about the 1000 other things from Dockerfiles, to Relational database query plan optimisation, to the latest azure cloud offerings, to the newest React library for managing state, etc. etc.
Most of the experienced developers you mention probably also don't know really know assembly - unless they are specialists, something which the generation before them think shows their lack of understanding. Assembly used to be canon, now it's a speciality. I don't know a single developer in my company who is able to write it.
We'll see if JHipster and their ilk are really the new building blocks. A lot of the older RAD development tools have also gone the way of the dinosaur. For sure the new primitives will be higher level and allow us to build more complex applications, it's just a matter of time before we'll find our which ones have to most expressive power and ergonomics, and which turn out to be giant hairballs.
This is an unnecessarily antagonistic rant, which boils down to “I know git from scratch, I’m so smart, why isn’t everyone else doing this”.
Git is a very complicated, bloated command line. Frankly, most of the day-to-day can easily be done with a high level understanding and a GUI. There is no shame in not knowing the minutiae of git.
The goal of being a programmer is to produce cool things, not to duel with your tooling.
I don't know git from scratch, never written it or dived into source code itself.
Yes, you can write C without understanding poinnters, you can paint without understanding colors and how they mix, draw without knowing difference between 3H and 2B, use a drill without knowing which type of head is for what.
But try doing it long term and you either gotta learn those things or your output will be limited and clear expression of your vision will be harder.
I'm not advocating for people to learn git from scratch.
I'm advocating for understanding - not low level, at least high level.
And is it better to go through a "how to use X tool in Y GUI" tutorial or how to use "X tool" and then gain immediate understanding of what Y does? What if you switch GUI's? Which knowledge will be sticking?
> I'm advocating for understanding - not low level, at least high level.
It sounds a lot like you mean low-level, not high-level, though?
There’s more than enough to be achieved by just knowing the tree concept of git, and using a GUI to visualize it while running the basics - checkout, commit, branch, rebase, etc.
>There’s more than enough to be achieved by just knowing the tree concept of git, and using a GUI to visualize it while running the basics - checkout, commit, branch, rebase, etc.
Oh, that's exactly what I meant. At least basic, high level understanding of the git model and basic operations on it. But most people never even get to rebasing or try do understand what lies behind magical buttons in the GUI.
C is a great example here. If you write a lot of C, you really have to understand pointers very well. And quite a lot else. That makes it a bad tool for many purposes, so most developers do not use it, and fewer use it every year. It's just a bad tool for modern purposes.
The same applies to the git CLI. And really, to git. The right tool for a small group C-using kernel developers 15 years ago may not be the right tool for different people doing different things today. Let's hope it goes the way of C.
Except you don't need to know the git CLI except when you've screwed something up. Even the reflog is available via TortoiseHg. Bisect okay maybe you have to drop to the command line, but otherwise there's no reason to futz about it when you can checkout, merge, rebase, cherry-pick, create new tags, etc. using the GUI.
My experience is that knowing the DAG in GIT is equivalent to needing to know pointers to write effective C.
Knowing the internals is more like needing to know assembly in C. Yes, it can be really useful for debugging certain classes of problems, but not really necessary in day-to-day work.
I've used git professionally for 4 years now and haven't once run into a corrupted repo or a problem googling for help couldn't solve. Day to day driver is TortoiseGit, which is frankly just a shitty TortoiseSVN skin on top of git. But I like being able to visually see the graph since at the end of the day I'm doing graph operations when manipulating the repo.
The irony with git is that the underlying data model is far simpler than the user interface implies. People assume git is complicated because the user interface is complicated, but it really is very simple under the hood.
So much so that you can write your own basic version of git in a couple of hours: https://wyag.thb.lt/
The problem is that git leaks the underlying data model all over the place, even where it's unnecessary to actually controlling versions. It's a nice data model, but the user view shouldn't expose it. The data model is an implementation detail, but git treats it like a show & tell.
But this isn’t a problem because the underlying data model is almost perfect for version control of text files. In some cases the data model is an implementation detail but in this case the porcelain is the fungible detail that can change depending on surface things like people's preferences.
You have it exactly backwards, and I think it gets to the core of why people get so unnecessarily confused about git. The underlying data model is both much simpler than the interface and crucial to understand. If you treat git as a collection of memorized command recipes the same way you did with SVN or CVS, you're going to have a bad time. The underlying DAG needs to be top of mind when interacting with git, as it best represents the inherent complexity of the problem that code repositories are meant to solve.
This attitude mystifies me. The whole point of computers is to solve problems well enough that most people don't have to understand the machinery.
It is literally impossible for us to understand how everything we use works. We expect a compiler to just compile things and work; nobody is ranting about how modern developers are lazy because they can't hand-verify the compiler is outputting the right opcodes. Nobody is ranting about how web developers are lazy because they can't debug a browser runtime and its interface to the OS's rendering primitives. Can some people do those things? Sure. Do we imply character flaws for the 98% of developers who have focused on other things? No.
If this old-man-yells-at-clouds, good-enough-for-grandpa-so-its-good-enough-for-me style were the dominant approach in our industry, we'd still be working with punch cards and fanfold printer output. Thank goodness it isn't. Instead of having a million developers adapt to git, git should adapt to the million developers and free up their time for doing something that actually matters to a user.
>Instead of having a million developers adapt to git, git should adapt to the million developers and free up their time for doing something that actually matters to a user.
How should git adapt?
Can you get a simpler model than this?
Is really a basic structure like a tree so complicated millions of developers are having a hard time with it?
Nobody is advocating for "dont use new stuff, old is betteer". Nobody is advocating for people to hand-check compiler outputs (unless your analogy pertains to people who work in a GUI tool that shows them pretty pictures for opcodes and they check if the pictures match).
You've missed the point.
The point is "try to understand the basics of the tool you are using".
If me wanting people to learn and understand more makes me an asshole, so be it.
I'd rather be an asshole and help people learn more and understand more than coddle them in the safety of the pretty buttons and say "it's ok, you don't have to understand".
If we don't understand our tools and the problems they solve, how will we make progress?
How will we make better tools?
How will we make better software?
How do you learn and grow if not by understanding what you don't?
One way it could adapt is by doing exactly what this article is talking about: Giving commands for common operations where name and behavior matches user intent.
That you can't tell the difference between "let's make software more usable" and "nobody should learn anything ever again and just soften into blobs of undifferentiated protoplasm" seems like a you problem.
My conflict resolution skills have atrophied due to jetbrains. It’s just so much easier than anything else I’ve tried. Even when I don’t already have a project opened in idea, I’ll open it just to resolve a merge conflict.
The rest I do on the command line because I don’t want to forget — except commits because I’m not at risk of forgetting “git commit -m”.
TL;DR because 'checkout' was found to be confusing, as of git 2.23 the switch command can switch to branches or commits (git switch master, git switch 0c38cf) and the restore command restores files (git restore pufferfish.txt).
I don't find switch or restore confusing? And also I never found checkout confusing, but that might only have been because I never realized it had multiple functions. I've been using it for both things (switching and restoring) for years, but I remember starting to read the article and thinking: how did I never notice this is the same command for two completely different things?! Maybe I used to know and now it's just not something I think about anymore? Either way, I can see how checkout can be seen as odd, but why switch or restore?
And I think arguably modifying working-directory files vs. modifying .git/HEAD are distinct things (though at this point I also find using checkout for everything to be pretty intuitive).
switch being underloaded to checkout is the same as checkout being overloaded to switch.
In the checkout model, branches are just named aliases for their current hash. This seems trivial to me. Do we really need to use another vocabulary spot up in our heads for a command that is strictly a more-restricted checkout?
> Yea it never bothered me and I never understood why people kept complaining about it online. It seemed very superficial complaint.
Consistency may be superficial to you, but that's a personal preference that not everyone shares.
> The way you use git is by first understanding its model. If you understand the git model, everything makes sense
Doesn't follow. I think I've got at least an acceptable handle on git's model, but I can't see how that should mean I'd have to accept that wildly inconsistent command switches "make sense". Care to explain how one leads to the other?
-b in checkout is short for "branch" while -c in switch is short for "create".
IMO the UI of git switch is much more intuitive, since the argument is always a branch and the default behavior is to switch to an existing branch. For slightly different behavior (like creating the branch first) there are flags.
So I think it's good that the flag for switch is a different one than for checkout, since the interface of git checkout was quite unintuitive IMO.
The complaint has been, for ages, that checkout got that wrong. As designers, these developers are improving: They got it more right on the second try.
It's not the correct solution because it requires knowledge of the intent of the project leaders, which is not easily available to us.
A much better response would be, "Thanks for pointing that out! I have filed an issue." One can't simultaneously through shade for not being community-spirited while expecting other people to do all the work.
Submitting a patch would start with filing an issue right? And I assume in that venue the maintainers would clarify their intent. If help were indeed needed then I’m sure the maintainers would be relieved to get some help fixing the documentation but.
In any case, the suggestion of submitting a patch when you notice a problem doesn’t deserve downvotes. That’s not throwing shade, at all.
There are ways to suggest submitting a patch that don't come across as dismissive, as a way to shut down a legitimate complaint. But this wasn't one of them.
I have trouble imagining you can't figure that out on your own. If that's really the case, then take a little time and explain exactly what impact you think that comment would have had on the person they were replying to. Then explore some other ways to actually encourage submitting a patch. Write a couple of them out.
If you do that work, I'm glad to try to help you see where their approach falls short in terms of sincerely encouraging contribution.
> I have trouble imagining you can't figure that out on your own.
I'm not being coy, as if I really know what you think, but I'm asking anyway just to be frustrating. I mean, I have an idea, but I also didn't want to make assumptions about your intent, when it's just as easy to ask you to elaborate. After all, it's your point that it was incorrect, so I just wanted to know why.
Any way, you said there are "legitimate ways to suggest submitting a patch, but this isn't one" (I'm paraphrasing). To me that didn't really make sense, because that implies one of the wrong ways to suggest submitting a patch is to suggest submitting a patch.
> If that's really the case, then take a little time and explain exactly what impact you think that comment would have had on the person they were replying to
In my mind, it seems like the effect that it would have on them is to suggest to them to submit a patch. Alternatively, it might also have no effect, because they might not care enough to do anything about it, or just be busy, which is also ok. They don't have to listen to any advice, and it was given in good faith, without malice.
I can also imagine a situation where it is technically possible for someone to attribute all sort of weird malice to "so submit a patch" that wasn't actually there. After all, people can feel however they want. However, in my opinion it's quite rude to assume about someone without knowing them that they're such a fragile creature as to invent malcontent where there is, in my eyes, obviously none.
So going back to when I said "I have an idea", I meant that yeah I can imagine, after this back and fourth, that maybe you would assume something like this about someone else - that they can't hear "so submit a patch" without taking it en every wrong way possible - but I didn't want to make that assumption without at least giving you the opportunity to explain yourself.
Ok, on to exploring other ways to encourage them to submit a patch. You could say, "Do you know you can submit a patch?", "Feel free to submit a patch", "This looks like a documentation bug, would you submit a patch?". All of these also seem fine to me.
> If you do that work, I'm glad to try to help you see where their approach falls short in terms of sincerely encouraging contribution.
What I don't like about this, personally, is that you're convinced their suggestion wasn't sincere, as if there has to be an ulterior motive. As if believing that a programmer on a startup forum is capable of fixing a documentation bug is so crazy, there can be no other explanation than really they were trying to humiliate the other person.
Any way, I do believe that you're trying to be helpful and it's not really that big of a deal so no worries. Hope you can believe me when I say I'm being sincere as well. Basically, a lot of people have different ways of encouraging each other, and there are a lot of different styles of encouragement that people appreciate. It doesn't mean that one you don't agree with is wrong. When I read "so submit a patch", my mind didn't immediately go negative, and I hope the recipient of that didn't either.
I'm not convinced of anything based on one terse reply. But given the history of replies like that and given the user's history, it's my best guess that they were not intending to be helpful. I read them as being dismissive in a way that shuts down a complaint.
If I wanted to actually invite somebody to contribute to an open-source project, I'd start with positive reinforcement. "Great point! That's definitely an issue with the docs." I'd then first tell them how to let the right people know about the problem. "You can file an issue here Be sure to categorize it as X, mentioning Y, and Z." Then I would explain that if they wanted to get involved in the project, they could try submitting a patch, giving them at least a few sentences of instruction on what files to look at, where to find the contributor guidelines, etc. In sum, if I'm asking somebody to do work, I'd encourage them and do a little work myself to show that I'm trying to support them.
So if that reply truly seems fine to you, please understand that if it ever was, it has been ruined by a long history of people acting like that to be dismissive or jerky. That rudeness is something I can almost excuse in someone actually working on an open-source project, as they can get a raw deal. But I think there's no place at all for it in a forum like this.
> "Thanks for pointing that out! I have filed an issue."
This means, here's my problem, someone else fix it for me. Since it has not been fixed for YEARS, maybe not the best alternative if you want to get it fixed.
If it truly hasn't been fixed for years, then either the people involved haven't noticed or don't care. If the former, filing an issue is helpful. If not, filing a patch may not get anything fixed either.
It is more likely that "the people involved" are working on other things or just don't share your concern. Filing a ticket can be helpful, but a pull request is usually preferred times 10,000. You are right, it is also possible that a change may mot get merged... In which case you've added the feature so the software is more useful to you anyway. Everyone wins.
Everyone wins if I have to maintain my own branch forever just to fix some documentation that I don't need because I figured out what was going on well enough to write a documentation update?
When you checkout a specific commit and are now in detached HEAD state, you are by default given the message
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
For some time I was pretty annoyed that git was showing the new suggestions, but for some reasons my git autocomplete did not know about them and thus couldn't tab complete. (It was on ArchLinux with zsh using the grml zsh config).
After a few month the autocomplete got updated as well and I could actually use the new interface without to much frustration.
Most of those are plumbing. They're only needed if you're building tools on top of git (integration with IDEs or custom GUI, for example), or doing very advanced scripting/broken repository repair.
The problem is that this breaks down when you specify both arguments. Doing `git checkout branch file` checks out file from branch to the working tree, but doesn't change HEAD.
The two are added with some extra protections. Something that cannot be done with git-checkout without breaking scripts.
I believe git-checkout could silently overwrite data in one case (can't remembe the details). And git-swith will stop you from moving the branch when you're in a middle of a rebase or other multi-command operations. It also tries to avoid entering detached HEAD mode by default.
It's definitely geared towards newcomers. But even I'm glad it catches me from doing stupid things from time to time.
I used to use Git Legit: https://frostming.github.io/legit/
But the official addition of git switch conflicted with their git switch (which is better as it auto-stashes changes before switching). Legit also had the issue of not properly handling branches with "/" in them.
My git productivity hack is `git diff --color-words`. Instead of showing the line-by-line diff, it shows only the words that changed. Especially useful if you have long sentences where only a comma changed or some other typo. With git diff, the two lines are shown, with --color-words, only the changed symbol is highlighted. The option --color-words also works with git show. I even made aliases for them: git cshow and git cdiff.
Other than that, I recommend that people learn to use git properly. In my work, I often have problems with people overwriting their commits and trying to handle merge requests of commits where one commit message is "did some updates" and the other commit is "some fixes". Getting to know git for an hour, may have prevented both issues. But I am biased, since I use git since my bachelor thesis.
> Other than that, I recommend that people learn to use git properly.
Sorry to be harsh here, but that is completely useless advice. It's a tautology. Of course people should learn to use git "properly". What's the alternative, that they should learn to use it improperly? Everyone should learn to use everything properly. It's like telling someone dealing with a crisis that they should "take appropriate action", as if taking inappropriate action was something that someone would actually seriously consider absent this advice.
The problem is that no one knows what "properly" means when it comes to git. Git itself provides no clue, and everyone and their second cousin has an opinion. That makes the advice to use git "properly" utterly vacuous. Figuring out what "properly" means is the whole problem with git.
> What's the alternative, that they should learn to use it improperly?
Yes. Or at least, avoid learning anything if they can help it, treating it as a black box that can never be understood. "Learn got properly" just means "actually make an effort to learn the tool rather that clinging to learned helplessness".
A viable alternative my coworkers seem to have adopted is, “Execute the git commands blindly as provided by me and get upset with git when something doesn’t work right.”
> Figuring out what "properly" means is the whole problem with git.
I think you've missed OPs point by focusing too much on a single word ('properly'). Yes, there's no clear-cut way on how to use git, no silver bullet, but the main problem with git is that most devs simply panic when they have to do anything that goes beyond the bog-standard commit/pull/push/merge. Rebase? Squash? Reset? Rebase interactively? I think OP was referring to this cluelessness with 'not using properly', rather than which approach to git is the best.
I work on a monorepo with 40-something other devs, and we've recently switched to enforced linear history because the history got to the point of being completely useless, it was an unreadable spiderweb. The problem was not that folks didn't see that what they were doing was not-so-good (introducing often more merge-commits with every PR than non-merges), it was that they had no clue how to avoid that.
It took us quite a bit of time to get everyone up to speed but pretty much everyone got around to it after a while. It's not rocket science after all.
Regarding your first point (and I think some of the commenters in that thread also address this already) is that as long you don't have uncommitted changes, you're safe. You're right that a lot of git-commands mess with uncommitted changes in hard-to-recoverable ways, but once changes are committed, there's almost no way to mess anything up, you can always go back to the previous state (git reflog <branch> telling you which commit that was).
Regarding the second point - if you have a rebase-based work-flow, you will encounter this problem less often (or not at all).
For your third point - what helped me a lot is to actively distinguish between commits and the working tree, and making myself aware that branches really are just "pointers" to commits (obviously, but somehow, actively thinking about it made the intent of git commands a lot easier to understand). Also, most git commands are just combinations of other commands. git reset is just moving the pointer (--soft without touching the working tree, --hard will do so), rebase is essentially a hard-reset with consecutive cherry-picks afterwards, and so on.
Also, an eye opener for me personally has been that e.g. an interactive rebase with squash towards a branch that is strictly ahead of you except for the commits you want to rebase is essentially just a "git reset --soft <target>", and then recommitting everything with a fancy commit-message. This and similar mental gymnastics with git-commands has helped me a lot; most of them really are quite sane (except for all those crazy options), "git checkout" is really the odd-one-out of the bunch (and "git pull" a combination of things that should never have been combined in the first place).
Honestly, if you were less busy sulking about it you might have had some capacity left to be receptive, in stead... And then it might actually have helped clarify a lot.
Also: In a discussion where one party is being helpful and the other sullenly sarcastic, it's not the helpful one that comes off as an asshole.
I really am not sure if you were being sarcastic or are really that unaware what a mish-mash of specialized jargon you just threw at the guy.
Don't think you the proponents actually understand the problem. It's not that programmers are unwilling to learn (something that many elitistic people love to pretend so they look smarter), it's something called tool fatigue. You just want your tools to do their job and move out of the way which GIT absolutely does not do.
I know that one day I'll get completely sick of GIT and will research and learn it to the bone. Sure, it's bound to happen. But the fact that GIT imposes its internal data model on you and doesn't attempt to solve more problems for you from the get go is what many of us are ticked off about.
> I really am not sure if you were being sarcastic
I was not :P But the commenter also said in the linked comment that they "understand how git works", so I took the liberty to make a few assumptions ;)
> But the fact that GIT imposes its internal data model on you
It does, to some degree, but once you get a grip of "everyday commands" that go beyond commit/merge (cherry-pick, rebase, reset, reflog), it's actually almost surprising how little you have to know about gits internals. It does help to have an idea about them, though.
My main complaint about git is that most commands have too many options that make it do too many different things. And that resolving conflicts via command line is absolutely atrocious (something I actively avoid and discourage).
> I know that one day I'll get completely sick of GIT and will research and learn it to the bone
I can only recommend it! It's really not that hard as many people suspect (as I've mentioned, I have a bit of a habit of teaching people git at work). If you had any exposure to something computer science in the past, the puzzle pieces probably start to come together after some hours.
And it's probably one of the longer-lasting constants in our industry, so in my opinion, it's really worth it to know how to make good use of it.
I've tried the "rebase into a feature branch" workflow, which I think you are alluding to. Unfortunately, it always results in scary conflicts. So I go back to merging the main branch into my feature branch workflow, which works every time. I then hit squash in gitlab for my merge request, and no one is the wiser.
Should I be doing something different? As I said, rebase in that situation is disastrous. Many folks recommend it vigorously but are not around when things inevitably go wrong.
I don't know, most people I've seen "scared" by merge/rebase conflicts have simply been scared by the UI provided to resolve them. It's just a matter of spending a bit of time familiarising yourself with what you're seeing and understanding what the tools are doing.
There's a bunch of resources on that and once you wrap your head around what git is doing it shouldn't be too hard to figure out how to navigate conflicts.
Merge conflicts in a rebase can propagate through every commit in your feature branch (suppose that you modify a boilerplate line in 10 commits, and you get a conflict on that line in the rebase, you now have to solve that conflict 10 times possibly with some interference with nearby conflicts)
In many cases also there are problems with git being line oriented rather than token oriented, IMHO I would have expected language aware diffs (for definition of "words" and maybe parenthesis) for common languaged to be common place by now (maybe even with a language server support)
In my team we are lucky as most conflict are a matter of simply choosing a side and overwriting the other.
>Merge conflicts in a rebase can propagate through every commit in your feature branch (suppose that you modify a boilerplate line in 10 commits, and you get a conflict on that line in the rebase, you now have to solve that conflict 10 times possibly with some interference with nearby conflicts)
Yes, this is true. But in a lot of cases this is a relatively trivial fix. That being said, I do think git could do better here. But I have not had it happen very often (and usually I know when it's about to happen so I know what to expect).
> In many cases also there are problems with git being line oriented rather than token oriented, IMHO I would have expected language aware diffs (for definition of "words" and maybe parenthesis) for common languages to be common place by now (maybe even with a language server support)
Language aware diffs would be a neat idea indeed, but I guess the issue may be that now git would need to have metadata to tell it which language server to use for which file.
I wonder if it would be possible to give git a plugin system for diffs, just have an option to offload to a diff program which could handle the metadata separately.
> [...] in a lot of cases this is a relatively trivial fix.
> [...] I have not had it happen very often
Often it is simple but it is tricky and hard to practice. Part of the problem is not git fault, it is just that thinking in diffs is not easy.
> metadata to tell it which language server to use for which file
My understanding is that git already does this (via filename or custom helpers) for binary/text files, I believe that it is used only for newline conversion, but for most usecases filename-based rules in a gitignore derived syntax would be enough.
Currently for binary files git has heuristics described in gitattributes(5) and these only go as deep as text encoding autodetection and the ability to specify the text encoding of a file or mark a file as binary. It's not sophisticated enough to know what kind if file it's looking at outside of just that.
> Unfortunately, it always results in scary conflicts.
I think you're referring to what I call "conflict cascades"? E.g., you're 4 commits ahead of "master", and want to rebase on top of it - but you have a conflict with your first commit, and after you resolve it, this results in conflicts in the second one, etc.?
It's a very interesting question because it's one of the main pain points of rebase that simply does not exist with merge.
What I've found for myself is that it's very important to create "atomic commits", which do not rely on other commits to make sense or "be complete". For example, a very common thing that I see is "fix formatting", "fix tests" commits, because some build was complaining about something being broken. And it's often these kind of commits that create weird conflicts (especially the formatting ones) because just a lot of code is moved/refactored/added/removed etc.
But do these commits make sense on their own? For example, if you have a history as follows:
Does it make sense to ever check out <commit-1>? No, right, because that commit is broken - wrong formatting, broken tests. What you want is always <commit-3>. So why not just adding those changes directly to commit-1 by using commit --amend when committing or by using fixup in an interactive rebase.
This was of course just an example, but in my experience, if people follow these kinds of trains of thoughts - what can be in a separate commit, what should be together, etc., there is an inherently smaller conflict-cascade-potential, which pays off a lot when rebasing. On top of that, it also makes history generally more readable and individual commits more meaningful and easier to cherry-pick.
I've never understood - or used - rebase as a standard part of a workflow. And I've been using git for nine years.
What is wrong with a master branch whose history reads "Merged feature foo" after "Merged feature bar"? If you need more detail then check out the feature branch and git bisect to your heart's content.
I do wish that we could "archive" branches from the output of `git branch -a` but really it's not a big deal when branch names are prefixed by Jira ticket identifiers.
I had this opinion for the longest of times as well, but me and all the other devs I know who started using a rebase-based approach just don't want to go back.
I think it's also a bit a question of team size. If your project has just a handful of devs working on it, merge-commits really don't matter all that much. If there are a few dozen with a good amount of juniors on the repo (a bit over 40 devs in my case), the commit-history becomes an absolutely unreadable spiderweb, that's at least my experience.
At work, we want to move towards trunk-based development (merge to master goes straight to prod), but whenever master was broken, a look at the commit-history didn't really all tell you that much about the who, how and why without checking it out and digging into it. So we've recently started to enforce linear history, in which case it is immediately obvious without the shred of a doubt who's responsible. Analyzing the build became an absolute breeze, at the cost of having a bit of a harder time at "insertion"-point (which is perfectly fine, given the fact that after merge, it should eventually go straight to prod).
It took a while to get everyone on board, but it was really worth the efforts and can only recommend it (I most definitely will prefer a workplace that is open to such practices in the future). In general, most devs were also quite happy to be guided through the process, as it is clear that git is probably one of the longer-lasting constants in our industry.
Also, I can't repeat it enough; speaking from experience, most devs severely overestimate the complexity of cherry-pick/rebase/reset/reflog etc. Whenever I had sessions explaining it or helping someone out with a problem, they had their first "aha!"-moments after a few minutes, and after that with some do-it-yourself-experience most of them get there rather fast. Obviously, there are always a few outliers who need a little bit of extra-nudging and extra-help to stay in line, but those are usually the ones who often also need that sort of assistance in other areas so that's okay.
> I think it's also a bit a question of team size. If your project has just a handful of devs working on it, merge-commits really don't matter all that much. If there are a few dozen with a good amount of juniors on the repo (a bit over 40 devs in my case), the commit-history becomes an absolutely unreadable spiderweb, that's at least my experience.
git log --first-parent gives you a nice linear history of (generally) your top level merge commits. If you follow a PR workflow, it's PR-by-PR breakdown of activity. The DAG gives you the power to "explore the spiderweb" if want/need to, but also pull back and say "give me the high level over" (--first-parent). I still think a lot of the emphasis on rebase-only workflows would disappear if more of the graphic UI tools (including and especially GitHub) had a better --first-parent experience by default. With the GitHub PR flow it has always surprised me that the main commit log isn't just a --first-parent view with an optional drilldown experience.
Sorry to beat a dead horse, but I'd love to be convinced. Could you give me an actual example where you were able to review a commit log that had been rebased easier than it would have been had been merged? Or an actual example where a merged commit log was a pain where it would have been easier had it been rebased?
Maybe the advantage is for people who use graphical tools? I'm still in the stone age using Git in bash.
> I've tried the "rebase into a feature branch" workflow, which I think you are alluding to. Unfortunately, it always results in scary conflicts.
You never rebase something into something else, you rebase onto something. I suppose you meant you want to rebase feature branch onto master.
If you have conflicts, you'll have them anyway, regardless if you're merging feature branch into master, merging master into feature branch or rebasing feature branch onto master. Conflicts are not a consequence of rebasing.
I'm working in a feature branch, and after a day or three changes have landed in the main branch. Which I need to incorporate or my merge request will be behind.
When I pull from main (git pull origin develop) there are rarely conflicts. When there are they are easy to understand and fix. Clicking squash on my request hides all intermediate commits so history stays clear in any case.
When I try to rebase from main (git pull --rebase origin develop) often almost every file in the project is in conflict, and the conflicts themselves are incomprehensible. I then run rebase --abort and go back to the merge strategy.
I've tried this about four times in the last few years; no one is able to explain what went wrong. If I had to guess it may have something to do with me pushing the branch when creating it.
git checkout master
git pull => fetch and merge the new things on master
git checkout develop => go back to your work branch
git rebase master => simple rebase, no squash, no nothing. The conflicts are the same as you'd get with git merge
do not forget to force push the changes of your branch
git push origin --force develop => to update your branch on the server
You can skip the "checkout master + pull" part by using "git fetch origin master:master", or by using just "git fetch origin" and then "git rebase origin/master". Other than that, that's pretty much my workflow too :)
By "properly" - I mean not messing up your own or others work in unpredictable ways.
My dev team uses git properly. They are not some masters in a way that they know each command by heart. They often use visual tools or what is built into IDE. We just have general guidelines and everyone knows how to do basic moves like "get code from remote", "merge others work into your local changes".
We had people who always have problems like "GIT ate my homework", well they don't work with us anymore so maybe it is a selection bias.
But I don't think my team members were NOT studying git for months to get to that level, it just came as they go along. Visual tools help a lot really.
In the end I expect someone with any abstract thinking capabilities to be able to use GIT "properly" after a week of working within the team. Like pull new changes every day, create new branch, create a pull request, merge new changes into your working branch.
The alternative is trying to use git while doing your best to avoid learning anything more about it than you absolutely have to, which is what most git users do. This is a great strategy for many tools, but git is not one of them.
Don't use it blindly. Learn it enough that you understand those mystical incantations and aren't summoning Cthulhu by accident, only on purpose
Don't cookbook it, understand what the thing you're typing means. Don't use a GUI to abstract it away, be familiar with the CLI and what it's doing. Don't default to rm-rf when you get stuck, check git reflog and see if you can unfuck yourself first. Ask someone who doesn't have your problems how they're using it - it's possible you're "holding it wrong" in some obvious way, but in a way that masks the true problem that's biting you.
Some of my coworkers regularly have problems with git - I don't, and some other coworkers also don't. We all use roughly the same workflow, it's the people familiar with "what does pull --rebase really do?" that don't get into trouble and/or can get themselves back out of trouble, and the ones who always type the same command regardless of the situation that have problems.
In my eyes all you did with this comment is join the people your parent poster is arguing against; you kind of just reiterated the stance they don't like. Not sure how constructive such a comment is.
> it's the people familiar with "what does pull --rebase really do?" that don't get into trouble and/or can get themselves back out of trouble
Absolutely not my experience. No small amount of people who seem to be doing more with GIT than me regularly get into trouble. Has been the case in at least 7 companies so far. Check your selection bias.
> and the ones who always type the same command regardless of the situation that have problems.
People like you forget that we use tools to make our lives easier. Tools. Not a whole damned ecosystem of dyslexic scripts that can't make up their mind even on a common CLI switch convention...
> Learn your tools, inside and out.
I am not paid to know GIT inside out. I am paid to deliver and fix code and to not step on other people's feet. I am aware that the second part is what many deem to be an ideal case for knowing GIT inside out but not to me and not to almost all devs I ever worked with. I do indeed want to issue one command and be done with it.
GIT does a poor job of bringing remote changes into your branch, for example. As other commenters have pointed out, it can do much better, like detect concurrent identical changes -- which is something that happens often in big teams, people just swing by a module and fix a trivial bug and include it in a bigger PR. You can argue until the end of days that's not a good dev team practice but in the end these things still do happen and this supposedly amazing tool is supposed to handle it. Guess it isn't designed for that?
> It's possible you're "holding it wrong" in some obvious way
"Obvious", sure. As if I care what an index, staging area, reflog etc. are. I don't. But GIT's team has been stubborn. This article seem to show some desire to improve UX, which might go contrary to what you feel what GIT users should do. ;) So I'd say even their team is starting to recognize some problems and are working to address them.
GIT's problem is super classical in all dev tooling. The creator(s) directly exposed the underlying data structures and are putting the onus on the user to learn them inside and out. As opposed to actually making a good UX.
Stuff like, say, "git sync" (which should do "fetch" + try to merge/rebase main branch with yours) should have been no-brainer right from the start.
> I am not paid to know GIT inside out. I am paid to deliver and fix code and to not step on other people's feet.
Your argument is still the same as the other git detractors, and is still wrong.
It _is_ part of your job, it _is_ part of delivering and fixing code. It's the same as anything else you're using. It may be a larger surface area that you're exposed to, but it's no different from CI/CD, build systems or something like a package manager. You don't need to understand how pip or npm or maven works to deliver software effectively, but if you get into trouble you have no alternative to rm-rf.
> As if I care what an index, staging area, reflog etc. are. I don't.
If you don't want to learn it then stop complaining about how difficult it is to use. That's your problem, not git's.
All of those things are important to the power of git. If you don't want / refuse to learn about them then you're trying to build your software with a car stuck in first gear and complaining about how slow it is. STFU and RTFM.
None of this detracts from your final point, which is valid! Just because the UX is mediocre (at best) doesn't mean you can't learn it.
The issue here is GIT is way more complicated to learn, because it has 10.000 options that might do what you want to do or do something else entirely.
Imagine your deployment pipeline required you to manually craft TCP packages to send to your machines to deploy code...would you still say "it _is_ part of your job, it _is_ part of delivering and fixing code", or would you say "that is stupid"?
With GIT, you are spending more time on learning and battling the tooling required to deliver code, than actually writing and testing the code.
> Of course people should learn to use git "properly". What's the alternative, that they should learn to use it improperly? Everyone should learn to use everything properly
No, its not. The alternative is not to.
Time is not free. Learning a tool properly is an investment. Sometimes that's worth it and sometimes its not. E.g. i would never advise anyone to take the time to learn dc properly.
I've always found it interesting that Git gets a pass for its horrible UX by so many devs. The programming community wants to provide too many options for _everything_. If there's a tool you don't like, there are probably 10 other versions that do similar enough things that you can just switch. Devs are harshly critical of tools. And yet, with Git, the response just seems to be "if you don't like it you must just not _get it_." Which, I guess is fair, but I don't particularly understand why everyone has to "get it"? Why can't we expect a tool that's used by so many be intuitive? Or at least, _more_ intuitive? It feels a bit like hazing at this point. The post recently about `git undo` was great, I think, because of the frequency with which users encounter surprising and unintended behavior.
It continues to be kind of frustrating to me. It feels like a tool that should be wrapped in something else and never even brought up to 99% of users. A half finished idea on productivity and team centric version control (to get ahead of comments: I know it's not designed to be that, but that's how it's very frequently used).
It's not like there aren't more than ten different tools that do approximately what git does, but a little differently. There are also dozens of UIs on top of git. So the response to git's UI is not uniformly "RTFM", many people tried to provide alternatives.
>And yet, with Git, the response just seems to be "if you don't like it you must just not _get it_." Which, I guess is fair, but I don't particularly understand why everyone has to "get it"? Why can't we expect a tool that's used by so many be intuitive?
There are lots of UIs for git - many people on this forum will advocate for using one. My personal experience is that a UI manages to over-simplify the git workflow. It never quite allows you to perform all of the useful tasks you want, unless your use of git is very basic.
In a more general sense, git can also be considered quite conceptually simple; "getting it" is not the real problem most users have. The confusion about what commands do comes from the fact that users learn the tool backwards. No job bothers to teach a junior developer about the DAG and what commits, branches, and refs really are. Instead, they are forced to start with git's large and crufty CLI - so it's no surprise that it's hard to pick up any intuition about what's going on.
And that's a problem with lots of technical teaching, not just git. Since the focus is on getting immediate observable results, and not on conceptual understanding, users tend to learn how to use tools instead of how they work. That creates a culture of "I don't know what this is doing, and I'm too scared to mess with it" - basically the anti-hacker mentality.
> And that's a problem with lots of technical teaching, not just git. Since the focus is on getting immediate observable results, and not on conceptual understanding, users tend to learn how to use tools instead of how they work. That creates a culture of "I don't know what this is doing, and I'm too scared to mess with it" - basically the anti-hacker mentality.
yeah I guess I don't really align with the "Developers must learn the internals of all of the technology they are required to touch", and I don't really agree with the sentiment that that decision disqualifies one from "hacker mentality".
>I don't really align with the "Developers must learn the internals of all of the technology they are required to touch"
The DAG, commits, refs, etc. are not the "internals" of git - they are the basic building blocks of its mental model. Without them, there is no way to understand what git is doing - so it's no surprise many people think git is unintuitive, because they aren't taught what those concepts are.
The thing I'm saying is counter to the hacker mentality is using a tool as a black box, without understanding what it does and what it is trying to do. You don't have to read the code and know all the technical details.
Lots of users treat git as a small set of known commands that they execute in sequence until the repo is in the state they want; and any deviation from that happy path is met with a repo wipe and re-clone. A hacker should be happy to play around with various man pages and commands to build an understanding of what each command really does - and then be able to fearlessly mix and match commands, because they know how they are affecting the repo at each step.
> The thing I'm saying is counter to the hacker mentality is using a tool as a black box, without understanding what it does and what it is trying to do. You don't have to read the code and know all the technical details.
And I'm saying that this statement is just hustle culture nonsense.
> A hacker should be happy to play around with various man pages and commands to build an understanding of what each command really does - and then be able to fearlessly mix and match commands, because they know how they are affecting the repo at each step.
No true scotsman would use git without reading books about it!
This is just nonsense. Gatekeeping holier than thou nonsense.
I use SmartGit (there are many other visual tools), as I have no interest in untangling the utterly hostile Git command-line interface. Using the terminal to stage chunks of a file? No thanks.
I feel no embarrassment about it either. You may pride yourself in using Vim, while working on a multi-thousand-file project. You are a power user, good for you. Now go collect other time-wasting useless accolades, like Pokemons.
I think the point is is that it's worth learning it, subjectively speaking. People tell me to learn vim properly, but I really dont believe I'll gain much based on the sunk cost.
If one guy says "This shit doesn't work!" and the other says "This is how it works", then it seems more like knowing how it works, well, properly than "shaming".
Looking at diffs on the command-line is cute and all, but for anything substantial I doubt this will ever be as good as using a proper GUI interface. I like "meld". You have to install it, then run
Analogy still applies, though. If a room is smelly to you, you aren't going to hang around. So the people who spend time there are going to be ones comfortable with the funk.
To be fair, if you mean that these changes are “bloat” and that git should be kept “simple” (not easy but non-complex), I don’t think this has much to do with Linus, because as far as I know he’s no longer involved in the development of git.
Git was written to meet the version control requirements of the Linux kernel. It works well for that project's needs which are an outlier for most development needs unless you are working at FAANG scale.
Git is a perfect match our project's needs, which are so far from FAANG scale that it would be a joke to even compare them.
In our case, fully distributed development (no developers live or work within 1000 miles of each other), public repository, welcoming 3rd party PRs, strong use of topic branches, fully rebase-not-merge workflow. 600k lines of C++, 21 year history, on the order of 100 contributors, 2-3 core developers at any point in time.
There were other solutions, much less complex to deal with than git, but hey, they lacked the luxury of being an hard requirement to deal with Linux kernel and related eco-system.
I've used, over the years, RCS, SCCS, CVS, SVN, Bitkeeper and Perforce. I would not trade any of them for git at this point in time, primarily due to the way that git allows for both net-connected and disconnected development without any change in the workflow.
Kind of ironic to say "FAANG scale" here, since Google notoriously uses an enormous monorepo, and Facebook uses mercurial and has done considerable work to scale it.
(Myself, I've been heard complaining that git is overly complex, but the source code control systems that I used to use before git include Subversion, CVS and various Rational products and I have no desire to go back to any of them.)
I can't recommend pijul, but I can recommend keeping an eye on it. Pierre-Étienne Meunier is a ferociously smart guy, and he's convinced me that patches are the correct way to build a VCS, rather than snapshots.
I catch up on a forum a few times a year, asking myself if it's ready for me to switch a repo or two over and see how it goes. So far I have to answer no, but I'm hoping it's just a matter of time.
549 comments
[ 3.5 ms ] story [ 460 ms ] threaddistributing improvements after a large mass of old habits are spread around is something to be fixed
Currently, that's an ubuntu 18.04 machine at work and that doesn't have `git restore`, yet.
So is there any incentive to switch for the people who went through the trauma of burning the old ones in their soul ? (I often heard that knowing how it works internally makes git commands feel natural. I was lied to)
If you know the old ones already and don't make mistakes, it's fine not to use these, really. I consciously got the new commands into my muscle memory in case I'm pair programming or someone less familiar with Git is looking along.
And yeah, knowing how Git works makes it a lot easier to understand, but it doesn't make the commands more natural. (Except perhaps knowing when you can use a commit id instead of a branch name.)
(Every non-official build is made from a separate branch.)
It's apparently a business requirement to keep every branch around forever, and I'll just take your word for that. At that point, you can have an `origin` remote where work happens, and the CI can include a push to an `archive` remote which is append-only.
Lets you have a development environment where the existence of a branch on origin means that it's in-play, and everything exists on archive if it proves needful.
Git checkout and a few other commands also use it to separate branch and the rest of paths, because you could specify like this
-- help disambiguates that by being between the branch and the paths, soFrom the article, I was thinking that it was again a stupid confusing design for the cli to requires the -- even with a dedicated command.
One main issue with git is to not be consistent and logic with the comments. Always to use different way or option abbreviation for different command. For example having a space or a slash between repo and a branch in a command.
Actually, this one makes sense, once you understand the underlying model of how git works with remote repositories, which (imo) is fairly fundamental to a distributed VCS.
They're different arguments (in your words, having a space) when you're accessing remote repositories and have to specify the location it should access. You can always substitute an URL for a repo in this case, and they fail if you cannot connect to the remote repository.
In all other cases (having a slash), you're referencing a ref in your local repository. This is a local copy of the remote repository. That means that it always works offline, but also that it doesn't sync with the remote repository. You can also substitute another ref, such as a "local" branch.
git fetch origin main
git rebase -i origin/main
Git push origin localBranch:remoteBranch
For example, why not:
git push origin/remoteBranch localBranch
(And if you want to preserve saying that slash is just for local, you could say: origin:remoteBranch)
git switch -
For going back to the previous branch you checked out.
If you want to learn Git from the inside out, I wrote a two-parter that aims to explain Git from the inside out, focusing on the data-structure Git uses:
https://looselytyped.com/blog/2014/08/31/gits-guts-part-i/
https://looselytyped.com/blog/2014/08/31/gits-guts-part-i/
Finally, _if_ you have an O'Reilly subscription, I am currently writing Head First Git (first four chapters are in early release). If you are not familiar with the Head First series, its a rather unique format that involves using lot of pictures to explain ideas and traditionally the books move a lot slower than most technical books. Ideas/concepts are cemented using puzzles, quizzes, crosswords.
You can see a list of the existing ones here https://www.amazon.com/Head-First-Series-Books/b?ie=UTF8&nod...
Feel free to email me if you need any more resources—I have spent a lot of time teaching Git.
https://learngitbranching.js.org/
You lean in 30 minutes more than you learn in hours of reading documentation and experimenting
Never heard of switch /restore and will probably forget about it the next time I'm on the terminal.
Rebase and interactive Rebase is so well integrated for my use cases and I feel much more productive without having to switch context.
Reflog and bisect are when I nowadays switch to the terminal, have not discovered an equivalent last time I checked.
I think a quick skim of the available features in the docs would probably give a good overview. Then poking around.
This IntelliJ integration is the source of quite a lot of git problems in teams I worked with.
I'm quite flabbergasted by this - devs claim to know git on their CV, come in and know what "commit" is and how to use the IntelliJ UI, but don't even understand what its doing. And everyone is acting like it's OK and learning git is a "hard thing ill never need" and we should all use sourcetree or jetbrains. Or people just get so used to it and never understand what exists below it. They lose all sense of what they're doing and just think "the machine knows what I want". Then a vaguely questioned dialog appears - or something similar - and they cause clusterfuck upon their branch - or sometimes even other people's remote branches.
How do we allow our culture to be so lazy that people resist using one of the basic tools because "oh its hard I gotta remember 5 commands" and we find it OK? No wonder the plane is burning.
It's good that you still know that reflog exists, because a lot of "inteliij is my git client" users don't even know about it. Tho I'm still wondering, isn't it faster/easier to open intelliJ terminal and type a command or two than having to ope a whole new window and click around it? (also sorry if this sounds like an attack on you, it isn't! just really wondering!)
Also, re: OP: So basically 2 new commands were added that do what other commands already do, but people dont read the docs so we should add new commands so maybe people will read the docs for them?
It's hard to see the gaps someone else has, and wonder why they can't know what you know, but they may have some deep knowledge in a domain you are only superficially knowledgable in.
I agree we need to nail the basics, but this isn't 2002 anymore, and we don't ship Gold CDs to customers by running a build command on a single PC in the office. Our jobs are so much more complex and multi-faceted, and the oldbeard assumption that things are 'bare essentials' is eroded by the pragmatic realisation that we only have so many hours in the day.
Actually, I'm trying to look at it more from a "shallow sea" perspective - you have a problem and are given a tool to solve it. But do you not dive in just a bit to see "hey what is this tool" after you solve the problem?
Or after using it for a while?
UI is also something you have to learn how to use.
Sourcetree UI is as complicated as terminal for someone who never used it.
>I have to deliver products and deliverables, when and what do I focus on wrt gaps in my knowledge? Git? Unix commands? OWASP Security principles? Cache busting? global state management? ORM integrations with popular DBs? Kubernetes configs?
With that mentality, what do you ever learn?
Do you just keep on chugging year after year with "duct-tape the tools"?
Where is the joy in that? Where is the growth?
Are you always in a rush to deliver software without a moment to think?
You learn about the level you're using - like, are you using git daily? Just reading a tutorial or two and spending 5 mins a day with it in the terminal is going to do wonders for understanding it long-term.
>Barely understanding many fundamental tools is common these days for devs
It's common for someone starting to develop or starting to use a tool - hell, 8 years ago I have been as confused as "wtf is this git" as anyone.
Gradle was magic to me. Terminal was a dark and scary place.
That doesn't mean that it is okay to stay at that level.
If we accept "not trying to understand" as the new common, then we accept failure and ignorance as the new common.
We accept the world of broken software because people don't understand what they're doing - and we're telling them "you don't need to understand so don't even bother".
And hell, maybe that's gatekeeping, but fuck it, I'll rather be St. Peter at the gates than accept a world where learning and understanding is something "we don't have time for".
> With that mentality, what do you ever learn?
The way I understand it, this comment is saying you have to prioritize and work on the highest-impact areas. Of course you grow, but until a certain point you don't benefit much from knowing the guts of git more than Framework X.
I have never experienced any joy of creativity from using git, so it's not something I'm putting high on my list. Heck, learning Rust was 10x as good for my development as git, so I don't regret prioritizing that way.
I expect (hope?) that most people understand the git they use in their daily workflow... but that doesn't mean they have to have mastered every dark corner. Find a specialist (Stack Overflow :) when an unusual situation arises. If it's happening consistently, then I agree some more learning should occur.
>With that mentality, what do you ever learn?
>Where is the joy in that? Where is the growth?
>Are you always in a rush to deliver software without a moment to think?
There's nothing sexy about learning git commands for me
I'd rather spend that time on actual computer science fundamentals or even reading stuff like HTTP RFC than learning git quirks
You can use top-down knowledge to inform yourself on what concepts you need to learn, and you can ignore the parts of the domain you need right now. But you still have to learn them bottom up. Getting confused by the concepts you're using is a gigantic waste of time.
And the harder the concepts, the easier it is to get confused, so there's no trade-off.
Its probably a rhetorical question but I think its worth answering anyway.
Experienced developers had the luxury of learning git, say, over a 10 year period. I certainly know a lot more git than 10 years ago.
If you are a new developer thrown into your first real project and Intellij handles git for you so that you can concentrate on being productive then learning command line git takes a back seat.
I see this in many aspects of programming. One thing I am struggling with currently, is that JHipster generates applications in a user friendly way. JHipster is highly productive and seems like the future of programming BUT it means that there will be a generation of programmers that do not understand the MB of Spring Java code that is casually puked out by the code generator.
Its depressing to say it, but I think not understanding the tools is only natural and is probably the new normal in this age of complexity.
The depressing thing is I'm not talking just about off-the-shelf newbies, I'm also talking about experienced devs.
>Its depressing to say it, but I think not understanding the tools is only natural and is probably the new normal in this age of complexity.
Yes, unfortunately, this is becoming the new normal. But what is the next "new normal" after this? More complexity and obscurity? How long can we keep building that house of cards before it collapses upon us?
The "cognitive burden" of git comes as much from the tasks that it is occasionally required to make possible than anything else.
If the only git commands you ever use are push, pull, commit and checkout then its a very simple system with very little cognitive burden. But one day, you may need to perform a truly complex task with git that a simpler system with much less cognitive burden would just not allow.
I do not understand how "data interchange formats" are an issue here. What do you want to inter-operate with?
Note that we're specifically discussing the theoretical reason for git's usability woes. The costs of actually fixing them in git aren't trivial, of course.
I use the basic git commands a lot but the wider set not very often.
So maybe I should learn Git from first principles every year? Like a cop would practice at the firing range?
But I’m doing that on my own time. But then what about the 1000 other things from Dockerfiles, to Relational database query plan optimisation, to the latest azure cloud offerings, to the newest React library for managing state, etc. etc.
We'll see if JHipster and their ilk are really the new building blocks. A lot of the older RAD development tools have also gone the way of the dinosaur. For sure the new primitives will be higher level and allow us to build more complex applications, it's just a matter of time before we'll find our which ones have to most expressive power and ergonomics, and which turn out to be giant hairballs.
Git is a very complicated, bloated command line. Frankly, most of the day-to-day can easily be done with a high level understanding and a GUI. There is no shame in not knowing the minutiae of git.
The goal of being a programmer is to produce cool things, not to duel with your tooling.
Yes, you can write C without understanding poinnters, you can paint without understanding colors and how they mix, draw without knowing difference between 3H and 2B, use a drill without knowing which type of head is for what.
But try doing it long term and you either gotta learn those things or your output will be limited and clear expression of your vision will be harder.
I'm not advocating for people to learn git from scratch.
I'm advocating for understanding - not low level, at least high level.
And is it better to go through a "how to use X tool in Y GUI" tutorial or how to use "X tool" and then gain immediate understanding of what Y does? What if you switch GUI's? Which knowledge will be sticking?
It sounds a lot like you mean low-level, not high-level, though?
There’s more than enough to be achieved by just knowing the tree concept of git, and using a GUI to visualize it while running the basics - checkout, commit, branch, rebase, etc.
Oh, that's exactly what I meant. At least basic, high level understanding of the git model and basic operations on it. But most people never even get to rebasing or try do understand what lies behind magical buttons in the GUI.
The same applies to the git CLI. And really, to git. The right tool for a small group C-using kernel developers 15 years ago may not be the right tool for different people doing different things today. Let's hope it goes the way of C.
My experience is that knowing the DAG in GIT is equivalent to needing to know pointers to write effective C.
Knowing the internals is more like needing to know assembly in C. Yes, it can be really useful for debugging certain classes of problems, but not really necessary in day-to-day work.
I've used git professionally for 4 years now and haven't once run into a corrupted repo or a problem googling for help couldn't solve. Day to day driver is TortoiseGit, which is frankly just a shitty TortoiseSVN skin on top of git. But I like being able to visually see the graph since at the end of the day I'm doing graph operations when manipulating the repo.
So much so that you can write your own basic version of git in a couple of hours: https://wyag.thb.lt/
It is literally impossible for us to understand how everything we use works. We expect a compiler to just compile things and work; nobody is ranting about how modern developers are lazy because they can't hand-verify the compiler is outputting the right opcodes. Nobody is ranting about how web developers are lazy because they can't debug a browser runtime and its interface to the OS's rendering primitives. Can some people do those things? Sure. Do we imply character flaws for the 98% of developers who have focused on other things? No.
If this old-man-yells-at-clouds, good-enough-for-grandpa-so-its-good-enough-for-me style were the dominant approach in our industry, we'd still be working with punch cards and fanfold printer output. Thank goodness it isn't. Instead of having a million developers adapt to git, git should adapt to the million developers and free up their time for doing something that actually matters to a user.
How should git adapt? Can you get a simpler model than this? Is really a basic structure like a tree so complicated millions of developers are having a hard time with it?
Nobody is advocating for "dont use new stuff, old is betteer". Nobody is advocating for people to hand-check compiler outputs (unless your analogy pertains to people who work in a GUI tool that shows them pretty pictures for opcodes and they check if the pictures match).
You've missed the point.
The point is "try to understand the basics of the tool you are using".
If me wanting people to learn and understand more makes me an asshole, so be it.
I'd rather be an asshole and help people learn more and understand more than coddle them in the safety of the pretty buttons and say "it's ok, you don't have to understand".
If we don't understand our tools and the problems they solve, how will we make progress?
How will we make better tools?
How will we make better software?
How do you learn and grow if not by understanding what you don't?
That you can't tell the difference between "let's make software more usable" and "nobody should learn anything ever again and just soften into blobs of undifferentiated protoplasm" seems like a you problem.
The rest I do on the command line because I don’t want to forget — except commits because I’m not at risk of forgetting “git commit -m”.
It also never occurred to me that the checkout command was overloaded in that particular way.
And I think arguably modifying working-directory files vs. modifying .git/HEAD are distinct things (though at this point I also find using checkout for everything to be pretty intuitive).
In the checkout model, branches are just named aliases for their current hash. This seems trivial to me. Do we really need to use another vocabulary spot up in our heads for a command that is strictly a more-restricted checkout?
The way you use git is by first understanding its model. If you understand the git model, everything makes sense.
If you come to it expecting it to be a tool that magically does what you want, I guess you will be very disappointed.
Consistency may be superficial to you, but that's a personal preference that not everyone shares.
> The way you use git is by first understanding its model. If you understand the git model, everything makes sense
Doesn't follow. I think I've got at least an acceptable handle on git's model, but I can't see how that should mean I'd have to accept that wildly inconsistent command switches "make sense". Care to explain how one leads to the other?
KDE, git, and FreePascal / Lazarus.
IMO the UI of git switch is much more intuitive, since the argument is always a branch and the default behavior is to switch to an existing branch. For slightly different behavior (like creating the branch first) there are flags.
So I think it's good that the flag for switch is a different one than for checkout, since the interface of git checkout was quite unintuitive IMO.
With `checkout`, however, what does `-b` even mean? Branch?
That said, it'll sure take time before the majority of developers (including myself) get onboard with it.
Would a deprecation flag be a good idea for git?
I've been using the alias `gk='git checktout'` for years now.
Git has been my first terminal-oriented versioning control system. I've used TFS and other but never focused on the action name, just the icons.
Checkout branch/hash/file seems more potent than two different commands.
+ git switch is documented as "EXPERIMENTAL"
+ git --help lists git switch but not git checkout as an important command
This is a documentation inconsistency. It can't be both the canonical interface to use and experimental at the same time.
A much better response would be, "Thanks for pointing that out! I have filed an issue." One can't simultaneously through shade for not being community-spirited while expecting other people to do all the work.
In any case, the suggestion of submitting a patch when you notice a problem doesn’t deserve downvotes. That’s not throwing shade, at all.
If you do that work, I'm glad to try to help you see where their approach falls short in terms of sincerely encouraging contribution.
I'm not being coy, as if I really know what you think, but I'm asking anyway just to be frustrating. I mean, I have an idea, but I also didn't want to make assumptions about your intent, when it's just as easy to ask you to elaborate. After all, it's your point that it was incorrect, so I just wanted to know why.
Any way, you said there are "legitimate ways to suggest submitting a patch, but this isn't one" (I'm paraphrasing). To me that didn't really make sense, because that implies one of the wrong ways to suggest submitting a patch is to suggest submitting a patch.
> If that's really the case, then take a little time and explain exactly what impact you think that comment would have had on the person they were replying to
In my mind, it seems like the effect that it would have on them is to suggest to them to submit a patch. Alternatively, it might also have no effect, because they might not care enough to do anything about it, or just be busy, which is also ok. They don't have to listen to any advice, and it was given in good faith, without malice.
I can also imagine a situation where it is technically possible for someone to attribute all sort of weird malice to "so submit a patch" that wasn't actually there. After all, people can feel however they want. However, in my opinion it's quite rude to assume about someone without knowing them that they're such a fragile creature as to invent malcontent where there is, in my eyes, obviously none.
So going back to when I said "I have an idea", I meant that yeah I can imagine, after this back and fourth, that maybe you would assume something like this about someone else - that they can't hear "so submit a patch" without taking it en every wrong way possible - but I didn't want to make that assumption without at least giving you the opportunity to explain yourself.
Ok, on to exploring other ways to encourage them to submit a patch. You could say, "Do you know you can submit a patch?", "Feel free to submit a patch", "This looks like a documentation bug, would you submit a patch?". All of these also seem fine to me.
> If you do that work, I'm glad to try to help you see where their approach falls short in terms of sincerely encouraging contribution.
What I don't like about this, personally, is that you're convinced their suggestion wasn't sincere, as if there has to be an ulterior motive. As if believing that a programmer on a startup forum is capable of fixing a documentation bug is so crazy, there can be no other explanation than really they were trying to humiliate the other person.
Any way, I do believe that you're trying to be helpful and it's not really that big of a deal so no worries. Hope you can believe me when I say I'm being sincere as well. Basically, a lot of people have different ways of encouraging each other, and there are a lot of different styles of encouragement that people appreciate. It doesn't mean that one you don't agree with is wrong. When I read "so submit a patch", my mind didn't immediately go negative, and I hope the recipient of that didn't either.
If I wanted to actually invite somebody to contribute to an open-source project, I'd start with positive reinforcement. "Great point! That's definitely an issue with the docs." I'd then first tell them how to let the right people know about the problem. "You can file an issue here Be sure to categorize it as X, mentioning Y, and Z." Then I would explain that if they wanted to get involved in the project, they could try submitting a patch, giving them at least a few sentences of instruction on what files to look at, where to find the contributor guidelines, etc. In sum, if I'm asking somebody to do work, I'd encourage them and do a little work myself to show that I'm trying to support them.
And it's not just me. The "submit a patch" bit is a cliche bit of jerkiness, so much so that there are whole discussions of it. For example this: https://softwareengineering.stackexchange.com/questions/6874...
And this: https://softwareengineering.stackexchange.com/questions/8323...
And it's a long-standing problem in open source. This, for example, is more than 10 years old: https://xenoterracide.com/post/dont-say-patches-welcome/
So if that reply truly seems fine to you, please understand that if it ever was, it has been ruined by a long history of people acting like that to be dismissive or jerky. That rudeness is something I can almost excuse in someone actually working on an open-source project, as they can get a raw deal. But I think there's no place at all for it in a forum like this.
This means, here's my problem, someone else fix it for me. Since it has not been fixed for YEARS, maybe not the best alternative if you want to get it fixed.
The Git project has no issue tracker though.
When you checkout a specific commit and are now in detached HEAD state, you are by default given the message
Whenever I do git status, it tells me which files are changed and if I want to go back to their previous states, I can use got restore.
After a few month the autocomplete got updated as well and I could actually use the new interface without to much frustration.
Situation: Git has 137 difficult and unintuitive subcommands [2], and new users can't keep straight which ones they should use.
"Oh man, that's awful, let's add new subcommands that are clear, and do just one thing well!"
Soon: Situation: Git's CLI has 138 difficult and unintuitive subcommands.
[1] <https://xkcd.com/927/>
[2] Yup, seriously, as of 2.32. I checked.
- the commit you want to checkout, which defaults to HEAD
- the files you want to checkout, which defaults to everything
Simple as.
I believe git-checkout could silently overwrite data in one case (can't remembe the details). And git-swith will stop you from moving the branch when you're in a middle of a rebase or other multi-command operations. It also tries to avoid entering detached HEAD mode by default.
It's definitely geared towards newcomers. But even I'm glad it catches me from doing stupid things from time to time.
Other than that, I recommend that people learn to use git properly. In my work, I often have problems with people overwriting their commits and trying to handle merge requests of commits where one commit message is "did some updates" and the other commit is "some fixes". Getting to know git for an hour, may have prevented both issues. But I am biased, since I use git since my bachelor thesis.
Sorry to be harsh here, but that is completely useless advice. It's a tautology. Of course people should learn to use git "properly". What's the alternative, that they should learn to use it improperly? Everyone should learn to use everything properly. It's like telling someone dealing with a crisis that they should "take appropriate action", as if taking inappropriate action was something that someone would actually seriously consider absent this advice.
The problem is that no one knows what "properly" means when it comes to git. Git itself provides no clue, and everyone and their second cousin has an opinion. That makes the advice to use git "properly" utterly vacuous. Figuring out what "properly" means is the whole problem with git.
[UPDATE] See also my earlier comment here:
https://news.ycombinator.com/item?id=27580478
Yes. Or at least, avoid learning anything if they can help it, treating it as a black box that can never be understood. "Learn got properly" just means "actually make an effort to learn the tool rather that clinging to learned helplessness".
https://news.ycombinator.com/item?id=27580478
Perfectly explained here : https://xkcd.com/1597/
I think you've missed OPs point by focusing too much on a single word ('properly'). Yes, there's no clear-cut way on how to use git, no silver bullet, but the main problem with git is that most devs simply panic when they have to do anything that goes beyond the bog-standard commit/pull/push/merge. Rebase? Squash? Reset? Rebase interactively? I think OP was referring to this cluelessness with 'not using properly', rather than which approach to git is the best.
I work on a monorepo with 40-something other devs, and we've recently switched to enforced linear history because the history got to the point of being completely useless, it was an unreadable spiderweb. The problem was not that folks didn't see that what they were doing was not-so-good (introducing often more merge-commits with every PR than non-merges), it was that they had no clue how to avoid that.
It took us quite a bit of time to get everyone up to speed but pretty much everyone got around to it after a while. It's not rocket science after all.
https://news.ycombinator.com/item?id=27580478
Regarding the second point - if you have a rebase-based work-flow, you will encounter this problem less often (or not at all).
For your third point - what helped me a lot is to actively distinguish between commits and the working tree, and making myself aware that branches really are just "pointers" to commits (obviously, but somehow, actively thinking about it made the intent of git commands a lot easier to understand). Also, most git commands are just combinations of other commands. git reset is just moving the pointer (--soft without touching the working tree, --hard will do so), rebase is essentially a hard-reset with consecutive cherry-picks afterwards, and so on.
Also, an eye opener for me personally has been that e.g. an interactive rebase with squash towards a branch that is strictly ahead of you except for the commits you want to rebase is essentially just a "git reset --soft <target>", and then recommitting everything with a fancy commit-message. This and similar mental gymnastics with git-commands has helped me a lot; most of them really are quite sane (except for all those crazy options), "git checkout" is really the odd-one-out of the bunch (and "git pull" a combination of things that should never have been combined in the first place).
Also: In a discussion where one party is being helpful and the other sullenly sarcastic, it's not the helpful one that comes off as an asshole.
I really am not sure if you were being sarcastic or are really that unaware what a mish-mash of specialized jargon you just threw at the guy.
Don't think you the proponents actually understand the problem. It's not that programmers are unwilling to learn (something that many elitistic people love to pretend so they look smarter), it's something called tool fatigue. You just want your tools to do their job and move out of the way which GIT absolutely does not do.
I know that one day I'll get completely sick of GIT and will research and learn it to the bone. Sure, it's bound to happen. But the fact that GIT imposes its internal data model on you and doesn't attempt to solve more problems for you from the get go is what many of us are ticked off about.
I was not :P But the commenter also said in the linked comment that they "understand how git works", so I took the liberty to make a few assumptions ;)
> But the fact that GIT imposes its internal data model on you
It does, to some degree, but once you get a grip of "everyday commands" that go beyond commit/merge (cherry-pick, rebase, reset, reflog), it's actually almost surprising how little you have to know about gits internals. It does help to have an idea about them, though.
My main complaint about git is that most commands have too many options that make it do too many different things. And that resolving conflicts via command line is absolutely atrocious (something I actively avoid and discourage).
> I know that one day I'll get completely sick of GIT and will research and learn it to the bone
I can only recommend it! It's really not that hard as many people suspect (as I've mentioned, I have a bit of a habit of teaching people git at work). If you had any exposure to something computer science in the past, the puzzle pieces probably start to come together after some hours.
And it's probably one of the longer-lasting constants in our industry, so in my opinion, it's really worth it to know how to make good use of it.
Should I be doing something different? As I said, rebase in that situation is disastrous. Many folks recommend it vigorously but are not around when things inevitably go wrong.
There's a bunch of resources on that and once you wrap your head around what git is doing it shouldn't be too hard to figure out how to navigate conflicts.
In many cases also there are problems with git being line oriented rather than token oriented, IMHO I would have expected language aware diffs (for definition of "words" and maybe parenthesis) for common languaged to be common place by now (maybe even with a language server support)
In my team we are lucky as most conflict are a matter of simply choosing a side and overwriting the other.
Yes, this is true. But in a lot of cases this is a relatively trivial fix. That being said, I do think git could do better here. But I have not had it happen very often (and usually I know when it's about to happen so I know what to expect).
> In many cases also there are problems with git being line oriented rather than token oriented, IMHO I would have expected language aware diffs (for definition of "words" and maybe parenthesis) for common languages to be common place by now (maybe even with a language server support)
Language aware diffs would be a neat idea indeed, but I guess the issue may be that now git would need to have metadata to tell it which language server to use for which file.
I wonder if it would be possible to give git a plugin system for diffs, just have an option to offload to a diff program which could handle the metadata separately.
Often it is simple but it is tricky and hard to practice. Part of the problem is not git fault, it is just that thinking in diffs is not easy.
> metadata to tell it which language server to use for which file
My understanding is that git already does this (via filename or custom helpers) for binary/text files, I believe that it is used only for newline conversion, but for most usecases filename-based rules in a gitignore derived syntax would be enough.
I think you're referring to what I call "conflict cascades"? E.g., you're 4 commits ahead of "master", and want to rebase on top of it - but you have a conflict with your first commit, and after you resolve it, this results in conflicts in the second one, etc.?
It's a very interesting question because it's one of the main pain points of rebase that simply does not exist with merge.
What I've found for myself is that it's very important to create "atomic commits", which do not rely on other commits to make sense or "be complete". For example, a very common thing that I see is "fix formatting", "fix tests" commits, because some build was complaining about something being broken. And it's often these kind of commits that create weird conflicts (especially the formatting ones) because just a lot of code is moved/refactored/added/removed etc.
But do these commits make sense on their own? For example, if you have a history as follows:
Does it make sense to ever check out <commit-1>? No, right, because that commit is broken - wrong formatting, broken tests. What you want is always <commit-3>. So why not just adding those changes directly to commit-1 by using commit --amend when committing or by using fixup in an interactive rebase.This was of course just an example, but in my experience, if people follow these kinds of trains of thoughts - what can be in a separate commit, what should be together, etc., there is an inherently smaller conflict-cascade-potential, which pays off a lot when rebasing. On top of that, it also makes history generally more readable and individual commits more meaningful and easier to cherry-pick.
What is wrong with a master branch whose history reads "Merged feature foo" after "Merged feature bar"? If you need more detail then check out the feature branch and git bisect to your heart's content.
I do wish that we could "archive" branches from the output of `git branch -a` but really it's not a big deal when branch names are prefixed by Jira ticket identifiers.
I think it's also a bit a question of team size. If your project has just a handful of devs working on it, merge-commits really don't matter all that much. If there are a few dozen with a good amount of juniors on the repo (a bit over 40 devs in my case), the commit-history becomes an absolutely unreadable spiderweb, that's at least my experience.
At work, we want to move towards trunk-based development (merge to master goes straight to prod), but whenever master was broken, a look at the commit-history didn't really all tell you that much about the who, how and why without checking it out and digging into it. So we've recently started to enforce linear history, in which case it is immediately obvious without the shred of a doubt who's responsible. Analyzing the build became an absolute breeze, at the cost of having a bit of a harder time at "insertion"-point (which is perfectly fine, given the fact that after merge, it should eventually go straight to prod).
It took a while to get everyone on board, but it was really worth the efforts and can only recommend it (I most definitely will prefer a workplace that is open to such practices in the future). In general, most devs were also quite happy to be guided through the process, as it is clear that git is probably one of the longer-lasting constants in our industry.
Also, I can't repeat it enough; speaking from experience, most devs severely overestimate the complexity of cherry-pick/rebase/reset/reflog etc. Whenever I had sessions explaining it or helping someone out with a problem, they had their first "aha!"-moments after a few minutes, and after that with some do-it-yourself-experience most of them get there rather fast. Obviously, there are always a few outliers who need a little bit of extra-nudging and extra-help to stay in line, but those are usually the ones who often also need that sort of assistance in other areas so that's okay.
git log --first-parent gives you a nice linear history of (generally) your top level merge commits. If you follow a PR workflow, it's PR-by-PR breakdown of activity. The DAG gives you the power to "explore the spiderweb" if want/need to, but also pull back and say "give me the high level over" (--first-parent). I still think a lot of the emphasis on rebase-only workflows would disappear if more of the graphic UI tools (including and especially GitHub) had a better --first-parent experience by default. With the GitHub PR flow it has always surprised me that the main commit log isn't just a --first-parent view with an optional drilldown experience.
Maybe the advantage is for people who use graphical tools? I'm still in the stone age using Git in bash.
Thanks.
You never rebase something into something else, you rebase onto something. I suppose you meant you want to rebase feature branch onto master.
If you have conflicts, you'll have them anyway, regardless if you're merging feature branch into master, merging master into feature branch or rebasing feature branch onto master. Conflicts are not a consequence of rebasing.
When I pull from main (git pull origin develop) there are rarely conflicts. When there are they are easy to understand and fix. Clicking squash on my request hides all intermediate commits so history stays clear in any case.
When I try to rebase from main (git pull --rebase origin develop) often almost every file in the project is in conflict, and the conflicts themselves are incomprehensible. I then run rebase --abort and go back to the merge strategy.
I've tried this about four times in the last few years; no one is able to explain what went wrong. If I had to guess it may have something to do with me pushing the branch when creating it.
My dev team uses git properly. They are not some masters in a way that they know each command by heart. They often use visual tools or what is built into IDE. We just have general guidelines and everyone knows how to do basic moves like "get code from remote", "merge others work into your local changes".
We had people who always have problems like "GIT ate my homework", well they don't work with us anymore so maybe it is a selection bias.
But I don't think my team members were NOT studying git for months to get to that level, it just came as they go along. Visual tools help a lot really.
In the end I expect someone with any abstract thinking capabilities to be able to use GIT "properly" after a week of working within the team. Like pull new changes every day, create new branch, create a pull request, merge new changes into your working branch.
The parent's point still stands: No one is out there choosing to use git in "unpredictable" ways.
If someone is a software developer, for me basic requirement is having possibility to understand this.
Don't cookbook it, understand what the thing you're typing means. Don't use a GUI to abstract it away, be familiar with the CLI and what it's doing. Don't default to rm-rf when you get stuck, check git reflog and see if you can unfuck yourself first. Ask someone who doesn't have your problems how they're using it - it's possible you're "holding it wrong" in some obvious way, but in a way that masks the true problem that's biting you.
Some of my coworkers regularly have problems with git - I don't, and some other coworkers also don't. We all use roughly the same workflow, it's the people familiar with "what does pull --rebase really do?" that don't get into trouble and/or can get themselves back out of trouble, and the ones who always type the same command regardless of the situation that have problems.
Learn your tools, inside and out.
> it's the people familiar with "what does pull --rebase really do?" that don't get into trouble and/or can get themselves back out of trouble
Absolutely not my experience. No small amount of people who seem to be doing more with GIT than me regularly get into trouble. Has been the case in at least 7 companies so far. Check your selection bias.
> and the ones who always type the same command regardless of the situation that have problems.
People like you forget that we use tools to make our lives easier. Tools. Not a whole damned ecosystem of dyslexic scripts that can't make up their mind even on a common CLI switch convention...
> Learn your tools, inside and out.
I am not paid to know GIT inside out. I am paid to deliver and fix code and to not step on other people's feet. I am aware that the second part is what many deem to be an ideal case for knowing GIT inside out but not to me and not to almost all devs I ever worked with. I do indeed want to issue one command and be done with it.
GIT does a poor job of bringing remote changes into your branch, for example. As other commenters have pointed out, it can do much better, like detect concurrent identical changes -- which is something that happens often in big teams, people just swing by a module and fix a trivial bug and include it in a bigger PR. You can argue until the end of days that's not a good dev team practice but in the end these things still do happen and this supposedly amazing tool is supposed to handle it. Guess it isn't designed for that?
> It's possible you're "holding it wrong" in some obvious way
"Obvious", sure. As if I care what an index, staging area, reflog etc. are. I don't. But GIT's team has been stubborn. This article seem to show some desire to improve UX, which might go contrary to what you feel what GIT users should do. ;) So I'd say even their team is starting to recognize some problems and are working to address them.
GIT's problem is super classical in all dev tooling. The creator(s) directly exposed the underlying data structures and are putting the onus on the user to learn them inside and out. As opposed to actually making a good UX.
Stuff like, say, "git sync" (which should do "fetch" + try to merge/rebase main branch with yours) should have been no-brainer right from the start.
Your argument is still the same as the other git detractors, and is still wrong.
It _is_ part of your job, it _is_ part of delivering and fixing code. It's the same as anything else you're using. It may be a larger surface area that you're exposed to, but it's no different from CI/CD, build systems or something like a package manager. You don't need to understand how pip or npm or maven works to deliver software effectively, but if you get into trouble you have no alternative to rm-rf.
> As if I care what an index, staging area, reflog etc. are. I don't.
If you don't want to learn it then stop complaining about how difficult it is to use. That's your problem, not git's.
All of those things are important to the power of git. If you don't want / refuse to learn about them then you're trying to build your software with a car stuck in first gear and complaining about how slow it is. STFU and RTFM.
None of this detracts from your final point, which is valid! Just because the UX is mediocre (at best) doesn't mean you can't learn it.
Imagine your deployment pipeline required you to manually craft TCP packages to send to your machines to deploy code...would you still say "it _is_ part of your job, it _is_ part of delivering and fixing code", or would you say "that is stupid"?
With GIT, you are spending more time on learning and battling the tooling required to deliver code, than actually writing and testing the code.
You're doing it really really wrong if you spend more time learning git than writing your code. Even with its bad UX it's just not that hard.
No, its not. The alternative is not to.
Time is not free. Learning a tool properly is an investment. Sometimes that's worth it and sometimes its not. E.g. i would never advise anyone to take the time to learn dc properly.
It continues to be kind of frustrating to me. It feels like a tool that should be wrapped in something else and never even brought up to 99% of users. A half finished idea on productivity and team centric version control (to get ahead of comments: I know it's not designed to be that, but that's how it's very frequently used).
There are lots of UIs for git - many people on this forum will advocate for using one. My personal experience is that a UI manages to over-simplify the git workflow. It never quite allows you to perform all of the useful tasks you want, unless your use of git is very basic.
In a more general sense, git can also be considered quite conceptually simple; "getting it" is not the real problem most users have. The confusion about what commands do comes from the fact that users learn the tool backwards. No job bothers to teach a junior developer about the DAG and what commits, branches, and refs really are. Instead, they are forced to start with git's large and crufty CLI - so it's no surprise that it's hard to pick up any intuition about what's going on.
And that's a problem with lots of technical teaching, not just git. Since the focus is on getting immediate observable results, and not on conceptual understanding, users tend to learn how to use tools instead of how they work. That creates a culture of "I don't know what this is doing, and I'm too scared to mess with it" - basically the anti-hacker mentality.
yeah I guess I don't really align with the "Developers must learn the internals of all of the technology they are required to touch", and I don't really agree with the sentiment that that decision disqualifies one from "hacker mentality".
The DAG, commits, refs, etc. are not the "internals" of git - they are the basic building blocks of its mental model. Without them, there is no way to understand what git is doing - so it's no surprise many people think git is unintuitive, because they aren't taught what those concepts are.
The thing I'm saying is counter to the hacker mentality is using a tool as a black box, without understanding what it does and what it is trying to do. You don't have to read the code and know all the technical details.
Lots of users treat git as a small set of known commands that they execute in sequence until the repo is in the state they want; and any deviation from that happy path is met with a repo wipe and re-clone. A hacker should be happy to play around with various man pages and commands to build an understanding of what each command really does - and then be able to fearlessly mix and match commands, because they know how they are affecting the repo at each step.
And I'm saying that this statement is just hustle culture nonsense.
> A hacker should be happy to play around with various man pages and commands to build an understanding of what each command really does - and then be able to fearlessly mix and match commands, because they know how they are affecting the repo at each step.
No true scotsman would use git without reading books about it!
This is just nonsense. Gatekeeping holier than thou nonsense.
I feel no embarrassment about it either. You may pride yourself in using Vim, while working on a multi-thousand-file project. You are a power user, good for you. Now go collect other time-wasting useless accolades, like Pokemons.
[1]: https://github.com/dandavison/delta
I slightly tweaked the default config and it is great.
[1]: https://github.com/git/git/tree/master/contrib/diff-highligh...
Or maybe just don't shame people for not working the way you do.
Indeed, Linus has only one commit in the last 3 years, and is the #28 committer of all time.
https://public-001.gitsense.com/insights/github/repos?p=comm...
The changes were mostly pretty small as well, which would make sense given he has been hands off for quite some time now.
Git was written to meet the version control requirements of the Linux kernel. It works well for that project's needs which are an outlier for most development needs unless you are working at FAANG scale.
In our case, fully distributed development (no developers live or work within 1000 miles of each other), public repository, welcoming 3rd party PRs, strong use of topic branches, fully rebase-not-merge workflow. 600k lines of C++, 21 year history, on the order of 100 contributors, 2-3 core developers at any point in time.
(Myself, I've been heard complaining that git is overly complex, but the source code control systems that I used to use before git include Subversion, CVS and various Rational products and I have no desire to go back to any of them.)
I catch up on a forum a few times a year, asking myself if it's ready for me to switch a repo or two over and see how it goes. So far I have to answer no, but I'm hoping it's just a matter of time.
https://pijul.org/posts/2021-06-28-two-changes/
Like a new filesystem, you should have a backup system in place if you use this, but the system is being well tested.
C++ is by no means simple.
so maybe wait until that note is removed.