Hacker News new | past | comments | ask | show | jobs | submit login

Maybe I am a rube, but people bemoaning "complexity" of git just never strikes home with me. I started using it when I was 14, so maybe that is it (it was still fairly new, but it's all I've ever known) - I still only use a handful of commands.

git checkout, git checkout -b

git pull

git merge (mostly to merge master back into a development branch, or something like that)

git push

git restore (much more rarely)

git reset (even much more rarely)

Barely ever have I had to do anything but these for 99.999% of my workflow, and none of them seem particularly complicated unless you run into merge conflicts, but on every team there seems to be at least one pro "merge conflict" guy. Idk. Checkout is occasionally annoying when it forces you to stash unrelated changes to what you're doing, that's about all I can come up with.




I’ve found that people are either die hard rebase fans or die hard merge fans. Neither side can understand the other and I’ve never had it properly explained to me what the difference is or why I should care.


Rebase rewrites history to an extent. What I do (and this is also the advice in Pro Git for what thats worth) is use rebase when I'm working in local because its cleaner, but the moment anything ends up on GitHub, I use merge because I don't want to rewrite history that other people are aware of.

I am fine rewriting my own history on local because I know what I did, but not when its on GitHub because other people don't neccecarily know what I did.


I think this nails the difference in my workflow against people that tend to say it is difficult. In infrastructure commit history, which is often tied to CI CD processes that reach far outside of a repository and org - commit history is sacred. I need the absolute order of when things got merged in, because it provides a clean timeline to backtrack any issues. maybe I’m doing it wrong but every mature sysyem I’ve worked in basically operates this way. I suspect you run into more merge conflicts but I’m by no means a git expert.


The best I've found is the kernel development process: use both intelligently and give your branches a clean commit history before they're sent for review.

https://docs.kernel.org/maintainer/rebasing-and-merging.html


Merge = Smooshes two branches together into one. It keeps all the commits from both branches and creates a new "merge commit" to combine them. Doesn't mess with the commit history.

Rebase = Takes all the commits from one branch and sticks them on top of another branch, like stacking them in front. It rewrites the commit history to make everything look like one straight line.

I'm a rebase stan, but that's just my opinion.


One of the disadvantages of rebase is that it leads to a history where most of the commit have never existed in that exact form an any machine and so have never been built or run. This may interfere negatively with git bisect, which assumes that you can run and test the software at every commit. A squash and rebase workflow doesn't suffer from this problem, but then you end up with huge commits that may make it hard to pinpoint the exact change that causes a new misbehaviour.

Of course, having a merge based workflow doesn't guarantee that people only commit source that runs, so bisect might be broken anyway, and you get a messy history on top of that, unlike the beautiful clean line of a rebase based workflow, that makes it look like the system was developed by people of superhuman mental clarity.


Wait. If `git bisect` is anyway identifying merge commits only (since those are the only on history), how are you supposed to get advantage of the supposedly superior smaller commits?


`git bisect` hits every commit, not only merge commits. They're saying if you used squash-merge (which is a special kind of rebase), the small commits don't exist anymore so there's no way for bisect to find the small commit that caused the problem. Regular merges and non-squashing rebases both keep the small commits so bisect will find them.


Counterpoint: I do both.

There are situations that make one or the other clearly preferred within a repo, besides per-repo/org-consistency for more widely shared work. After a few years excavating in a merge-only-salt-mine as well as working orgs where merge commits are banned you get a feeling for what's helpful when (esp considering auditability and history legibility).

Always rebase incoming feature branch on the base branch before merging into a shared repo regardless of approach, though - "merged from main" inside a merge commit on main makes anything an inscrutable tangly mess very quickly.


`git merge` is for regular people who are measured by how much they can accomplish in a given timeframe.

`git rebase` is for academics and startups where no one gives a fuck about anything and no one bats an eye if you waste a day or two on a rebase gone wrong.

It's easy to undo a merge and a bit nasty if you already pushed the merge commit. But undoing a rebase? Oh god you're in for a lot of pain.


> But undoing a rebase? Oh god you're in for a lot of pain.

It's actually pretty easy. You either make a checkpoint tag before you start the rebase, and reset to it if you notice something went wrong; or, if you forgot to make the checkpoint, check the reflog and find the commit you started from, and reset to that.

Reflog has a flag which adds timestamps to every entry, which I find is helpful for this:

    git reflog --date=iso


This doesn't match my experience and it is almost exactly opposite of my personal preference of rebased commits. I get that you want to be incendiary but I think this misses the point, perhaps on purpose.

My good faith addition here: a major influence in this debate seems to me to be how a team views their repo. Merge heavy stuff makes great sense for a repo whose job is just to hold everything; essentially a big and powerful shared clipboard that has all the myriad work-in-progress. Almost like a "dumb" tool (and trust me when I say dumb with lots of love and respect - it isn't criticism it is about which direction coupling points). On the other hand, the rebase heavy approach makes more sense if you view the repo as a contextual knowledge store, holding an almost idealized version of the point in time, uncluttered by the reality of the path actually taken. To broadly generalize my experience, I've found the merge version is generally faster, has low overhead in the moment, and scales pretty well since it is nearly the lowest common denominator approach. Conversely, I've found the rebase version makes debugging and context switching faster and enables a leaner team to cover more ground because the repo has some context and documentation built in via its organization.

Of course, doing either approach poorly will have negative consequences and being inconsistent in either approach is worse than consistently doing one or the other.

I'm not trying to make an argument for which to choose but I am pushing back hard on rebase only being used by teams who are unprofessional and don't care about wasting their time.


the old commits are still in your reflog, and if they belong to a branch that isn't only on your machine, you can nag a coworker if you don't know how to use that


yeah, totally agree, it's so hard to type `git rebase --abort` (?)


Get out of here with your academic mumbo-jumbo


I think a lot of the people who use merge do so because that’s what they learned initially.

Anecdotally, a lot of my coworkers who use merge are conceptually trying to stack their commits on top of previous ones. My lukewarm take: most of the time, rebase is actually the intended operation and merge is used as a hammer.


People who are these fans don't really use git. They use github subset of git. Hence, all these problems. In my experience, people who actually use git instead of github don't have these issues.


I think everyone needs to know the existence of git bisect. That has the side effect of improving individual commits as you'll make sure whatever functionality they implement is atomic.


This is one of the ways I try to convince engineers of the value of atomic commits with good messages.


Amen brother haha I have not evolved at all in my git usage and it hasn't really hurt me in any way.

Its not really part of the job to deal with 'insane merge issues', or crazy git tricks and things, only once in a while...

Also, rebasing is so confusing at least in the cmdline sense, I don't see the point.


This isn't about complexity it's about git putting multiple commands into one and potentially doing stupid things as a result. (Even though I don't think I've ever actually had a problem where I said "git checkout <file>" and git interpreted it as a branch or vice versa. I mean, that happens but I think in every instance no such file/branch has existed so git did nothing.)

In any case, I think checkout does in fact conflate things that should be (at least) two separate commands. That's not "less complex" it's about having more predictable behavior. And arguably it's more complex than the status quo.


have you ever worked with other people on the same project? or Gerrit?

There's really nothing simple, quick or logical about Git when you need to do things like:

copy some files from another repo into yours while preserving file history

copying files within a repo while preserving file history (if you just copy+paste you lose, if you edit the files after moving with git mv, but before comitting the move first, you lose all history)

deleting 1 file from all commits in a repo (almost impossible without using an external non-git tool)

dealing with a rebase that was pushed that shouldn't have happened

I could go on and on with examples of things that should be trivial but aren't.


> have you ever worked with other people on the same project? or Gerrit? There's really nothing simple, quick or logical about Git when you need to do things like:

Yes, I currently manage my team's merge process and review all code that gets merged into our main repository. I tend to only do trunk-based repositories, work mostly in infrastructure, so I imagine my process is a little different than some traditional "dev" ones, but it's largely uncomplicated on my 5 person team.

> copy some files from another repo into yours while preserving file history

I'm not really sure what this means - I don't often have to do this, can't imagine why I would have to do this. If by "file history" you mean the commits on the file from the other repo? I can't imagine why I'd do that and it sounds like an anti pattern to me, and I avoid doing things like that at all costs, or would just create a git submodule if I really, really had to have that history and file in my repo for whatever reason.

> copying files within a repo while preserving file history (if you just copy+paste you lose, if you edit the files after moving with git mv, but before comitting the move first, you lose all history)

Really never have felt a need for doing this in any repository I've worked in so I guess no, for similar reasons as my above comment

> deleting 1 file from all commits in a repo (almost impossible without using an external non-git tool)

Why would you have to do this with any kind of frequency? If I did, and it was sufficiently complicated, I would put it in automation and write it once and call it a day.

> dealing with a rebase that was pushed that shouldn't have happened

I'm seeing now from other comments what the difference here is, I don't really ever use rebase and never have felt the need to. If I ever worked for a team where I didn't get to decide that, we had tooling that managed that part or wrote it.

> I could go on and on with examples of things that should be trivial but aren't.

I am a little curious, because some of what you wrote sounds a little bizarre to me, but I guess I'm probably in a much different domain.


> copying files within a repo while preserving file history (if you just copy+paste you lose, if you edit the files after moving with git mv, but before comitting the move first, you lose all history)

This is much closer a description to svn (and probably other systems), and doesn't describe git at all. Git doesn't store file renames. It reconstructs them from the history based on how similar an "add" and a "delete" were in the same commit. There's even args to change the sensitivity and look for line sources in even broader scopes* - which means git can do one thing others can't, show you where lines came from when two or more files were merged. Others can only show you one of the source files, the one that was explicitly renamed.

* See "-C" in "git help blame", the broadest scope even looks for the source in other commits.


Except that it can't, and doesn't, always work


Exactly. I have never ever had an OS "cut-paste" operation work in a way that git didn't see as entirely new files that it never saw before.

If it did work like that, there would be no reason whatsoever for the "git mv" command to exist.


> deleting 1 file from all commits in a repo (almost impossible without using an external non-git tool)

That seems like the exact opposite of the purpose of version control.


The classic example is accidentally committing a binary file or some other large-as-in-filesize garbage -- simply deleting the file preserves it in history, bloating the size of the repo.


Somebody accidentally checks in an AWS private key and it gets found out much later.


Then removing it from history doesn’t do anything because you already need to rotate the key


It ends up being a worthwhile thing to do if someone has checked in a large file that shouldn't be in git or whatever


It seems you don't think it's complex because you only learned a bunch of commands, and do basic things

And I'd bet you have little familiarity with its documentation, which in itself is one of the worst I've ever ran into.

The fandom around it, furthermore, with most saying it's awesome to not admit that they don't know it, makes things much worse


These are wild assumptions based on pretty much nothing except your own biases. Pretty sure people like you are far more insufferable than the imaginary person you’re railing against.


They're based on your message


You know absolutely nothing about what I know or have experience with based on that message.


> You know absolutely nothing about what I know or have experience with based on that message.

Sarted using it at 14, still only use a handful of commands, don't think it's complex


The most important one is

  git rebase


Don't think I've ever used this except by UI's from bitbucket/github etc. when doing a squash commit.


You never add files, create commits, or rebase?

Often people arrive on a team that has committed a grave sin in the past and all future team members are forced to use workflows involving submodules as penance.


i tried the newfangled commands and they are objectively worse.

maybe should fork a git lite that has only the commands you listed.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: