I think the reason why git beginners have a hard time with it is because the api is a bit untuitive.

For example: if you want to "unstage" staged changes, you run git reset, and if you want to "delete" those changes from your working copy, you git checkout those files.

But then, you find out that you can do all of that if you git add . and git reset --hard.
So you're like "huh..."

And then you discover that if you end the resethard with a branch name/commit id then you also make current branch point to the commit or that branch/commit (respectively).
So you're like "huh..."

And also if you add a commit id or branch name to git checkout, you change the current branch to specified/enter detached state with HEAD pointing to that commit (respectively).

Oh and you don't use git branch to create branches, you use git checkout -b because it's a lot shorter.

So here's a rundown: git reset mutates things related to files, but also mutates things related to branches.
git checkout also mutates things related to files and mutates things related to branches too (in a diff way). Also, creates new branches.

I don't think this is intuitive. We users use the same commands for different purposes with just a different flag.
Commands shouldn't mutate different types of things. But don't composite commands (as in, "smart" commands that mutate different things) shoudln't be a flag in an existing command, it should be a single new command of its own.

Maybe if I reread the internals of git now, I'll be able to disgest the dozens of technical terms they throw at you (they are many). And in my mind, the api will cognitively fit to the explanations.

Here's another one that feels weird too.
If you want to make your changes start on top of someone else's commit, you do git rebase.
But git rebase -i can be used for that, and also to delete, modify changes or message of, reorder or combine previous commits of the current branch.

Maybe the reason why several things we do overlap with the same commands is because they internally do similar things, and while not separating those commands might make it less intuitive, it makes them more sensible? i dunno...

disclaimer: I'm not setting this opinion in stone though, and am aware that git was created by one of the most infuential programmers.

  • 5
    If we want to stage/unstage files, why not create a stage/unstage commands?
    If we want to change current branch, why not use the branch command?

    another disclaimer: I'm not saying let's write a wrapper.
  • 1
    Guess we're writing a wrapper, boys!

    I'm new to git so I make a manual copy of src before rebasing because I'm afraid I'll do something catastrophic......

    Like, I have a local feature branch where I squash my commits into one before merging back to master. Is this OK? It doesn't seem to fuck anything up from what I can tell.

    Last week I pushed a feature branch in case my PC would die. But when I rebased that one I got a lot of conflicts that had nothing to do with my feature branch. It was like I was squashing all of master so I had to travel back in time and solve every old merge conflict on master again before even getting to my feature branch commits. Sounds familiar? Where did I fuck up?

    Thankfully this time a tool took care of tidying up commits and merging when my pull request got accepted. I'm still puzzled tho...
  • 1
    @erandria too late - JS frameworks for this have been spawned into existence just because you mentioned it.
  • 2
    @ihatecomputers never rebase while on master to avoid ass pain
    also, I'm not a huge of fan of squashing on every commit... I think the benefit of a clean log history is offset by the problem of having resulting humongous commits...
  • 1
    @erandria Ohh, that makes sense. Thanks 🙂
  • 1
    Git's UI is total crap because it was thrown together without any thought beyond somehow allowing feature access.

    This way of development is completely wrong because it is backwards, and the result is just as shitty as expected when disregarding any best practices with UI design.

    The ONLY domain where that is OK is for programs that are not meant for human interaction, i.e. programs that talk to other programs. Think compilers called via build systems, or something like Apache. These are the ones where you need configurability over anything else because you set it up exactly once and then don't touch it anymore.

    Doing that for an interactive program like Git results in a total disaster.
  • 2
    @erandria it's not just you. Over the years there have been dozens of articles criticizing Git.

    Once you understand Git's internals (I recommend "Git from bottom up") you get what its incantations do... but Git's shitty interface remains shitty. And as long as there's enough fanboys shouting down criticism nothing will improve.

    Toxic tool, toxic community. I avoid Git whenever I can.
Your Job Suck?
Get a Better Job
Add Comment