I am aware that beej's guides are typically quite comprehensive, but the vast nuances of git truly eluded me until this.
I guess Jujitsu would wind up being a much slimmer guide, or at least one that would be discoverable largely by humans?
I am aware that beej's guides are typically quite comprehensive, but the vast nuances of git truly eluded me until this.
I guess Jujitsu would wind up being a much slimmer guide, or at least one that would be discoverable largely by humans?
I've never found that I need to touch most of it in the 15 or so years I've been using it, but it's there if your project needs it.
The universe doesn't owe you an easy 10 minute video solution to everything, it's an annoying educational expectation that people seem to have developed. Some things are just that difficult and you have to learn them regardless.
And on that note, I feel like the guide covers maybe 10% of Git :), but hopefully 90% of common usage.
I can teach someone who has never even heard of source control how to use Perforce in about 10 minutes. They will never shoot themselves in the foot and they will never lose work. There are certainly more advanced techniques that require additional training. But the basics are very easy.
Git makes even basic things difficult. And allows even experts to shoot their face off with a rocket launcher.
Git sucks. The best tool doesn't always win. If MercurialHub had been founded instead of GitHub we'd all be used a different tool. Alas.
1. Create a branch from the intended destination.
2. Merge/rebase/whatever complex operation you need to do into that branch.
3. If successful merge this branch (fast forward merge) into the intended destination.
4. If unsuccessful delete the branch and start over at step 1.
1. it’s possible to get into a bad state 2. it’s not clear what exactly that state is 3. it’s not clear how you got into that state 4. it’s not clear how to get out of it
I understand Git reasonably well. I know a good bit how it works under the hood. When I have a gitastrophe I rarely understand what I did wrong and how to avoid it in the future.
Here’s a recent post from a friend:
“ 0) clicked fetch all to make sure I had latest everything 1) right clicked on master and selected "merge master into branch" 2) made sure there were no merge errors 3) get on the master branch 4) clicked pull again because sometimes switching to branches doesn't work without it 5) right clicked on my branch and selected "merge branch into master" 6) clicked check in and push buttons
About an hour later, someone noticed that everyone's work from the past week was gone. I mean the checkins were still there in the graph, but all their code was basically gone in latest. And because my branch had many commits in it, apparently no one could just revert my merge and it took someone an hour to work out how to fix everything during which no one could touch git”
Somewhere along the way he didn’t do what he thought he did. No one could figure out what he actually did wrong. No lessons were learned from this Gitastrophe.
Without knowing for sure what was going on and whether your friend was describing it using the right verbs, I'm thinking (0) didn't pull in the changes ("fetch" instead of "pull") so (1) didn't merge in any new commits, but (4) did advance master, causing it to diverge from what was on the server. Then (6) probably decided to be helpful and did a force-push instead of a regular push so it wouldn't fail on the user. That would cause the server to have your friend's changes, but be missing anything that had been pushed to master after they started working on their branch.
You need to think about what you're actually trying to accomplish, and that requires having a mental model of how the tool works. And no, I don't mean under the hood, I mean stuff like "what does a rebase do?" and "how do branches work?"
The Git Book is a great resource for this. I recommend reading it and trying the examples over and over until they stick. I promise, git is not inscrutable.
Probably you've been using it for ten years or more at this point and have internalized it, but when it came out git felt way more confusing than other VCSs.
Compare git diff with hg diff for example.
Most Git users will never have more than one remote per project, and so will only have a single product built from their source code. Probably wouldn't even know how to configure their mua to send text-only emails, in case that option is even available to them, and would struggle with basic Unix utilities like Vim and diff.
I don't know why Git won the VCS contest. But, I'm afraid, as with many such wins, there wasn't a clear rational reason why it should have won. It didn't make some of the obvious bad decisions which would disqualify it, but so did a few others. My take on this is that communication tools naturally gravitate towards monopoly, so, if one starts to win even slightly, the win will become a landslide win.
Here's a simple example of how people shoot themselves in the foot with Perforce all the time: it makes files you edit read-only, and then you run with your pants on fire trying to figure out how to save your changes, because the system won't let you do that. And then you do something dumb, like copy the contents of the file you aren't able to save someplace else, and then try to incorporate those changes back once you've dealt with the file that Perforce wouldn't save. And then end up with a merge conflict just working with your one single change that you are trying to add to your branch.
I never regretted never having to touch Perforce ever again. Just no.
It was a disaster. Literally the most important thing for any VCS tool is to never ever delete file I don't want deleted. No more Jujutsu for me.
Someday someone will invent a VCS tool that doesn't suck. Today is not that day.
Because GitHub offered free git hosting, and heroku came along and offered free hosting that was pretty much point and go.
Combined, you all of a sudden went from needing a sysadmin and two servers (this was pre containers), and the sysadmjn skills to operate SVN and your web app, to “it’s now free and it auto deploys when I commit”.
You shouldn’t ever need to go to the reflog unless you’re in an exceptional case, and fit makes it very very easy to get into that exceptional case.
How do I undo a change and get it to other people on the team?
- follow up, What happens if someone has made an unrelaydx change since?
- someone has committed an enormous change and I want the commit immediately after it but the enormous change doesn’t affect me. How do I get that single file without needing the mega change.
- someone has committed a mega change and pushed it to main, and it’s busted. How do I put my perfectly functioning feature in while i wait for the west coast to wake up and fix it?
I don’t need an explanation on how to solve these issues, I am perfectly able to. But these are daily workflow issues that hit requires you to use external tools, and change entire development processes to work around. And trying to skirt them is a guaranteed one way ticket to a busted workspace
I mean I haven't even talked about how Git can't handle large files. And no Git LFS doesn't count. And Git doesn't even pretend to have a solution to file locking.
I'm not saying Perforce is perfect. There's numerous things Git does better. But Perforce is exceedingly simple to teach someone. And it doesn't require a 193 page guide. I can teach artists and designers how to use Perforce and not lose their work. A senior engineer who is a Git expert can still shoot themselves in the foot and get into really nasty situations they may or may not be able to get out of.
There's a reason that like 105% of AAA game dev uses Perforce.
So, is it possible to deal with Perforce marking files read-only? -- Yes. And it's not complicated, but the whole idea that that how the system should work is stupid. The problem is, however, exceptionally common. In my days working with Perforce there hadn't been a day when this problem didn't rear its ugly head.
So, maybe Perforce is scoring better on some metric, but in the day-to-day it generates so much hatred towards itself that I don't care if it can handle big files better than Git does. I only need to handle big files maybe a few times a year. And I prefer to get frustrated only twice or three times a year than to be fuming every time I have to touch files in my project.
1. Git is complicated 2. Perforce is so simple to use that I can teach an artist or designer who has never even heard of source control how to use it in 10 minutes.
Then you came in and said the way Perforce handles read-only files is stupid. You know what, I agree! That's a solvable problem. If Perforce wasn't acquired by a private equity firm maybe they'd actually work to make it better. Alas.
This isn't about Git vs Perforce. I post in all of these Git HN threads because I desperately want people to realize that Git sucks ass and is actually really bad. WE COULD HAVE SOURCE CONTROL THAT DOESN'T SUCK. IT'S POSSIBLE. I'm not saying that Perforce is that solution. I'm saying that Mercurial and Perforce are existence proofs that certain things are possible. Source control doesn't have to be complicated! It doesn't have to have footguns! It doesn't need a 189 page guide!
What I'm curious about though, since I basically entered the software developer workforce just as Git became mainstream and GitHub became popular, how would you do those things with the alternatives at the time; SVN, Mercurial, Perforce and the rest? Would it be easier or harder? Would it work better/worse in a sync/async context, without centralized servers?
There are lots of people complaining about how needlessly complicated git is, but they almost always fail to put forward some simpler alternative that can handle the same things. Is git actually accidentally complicated or purposefully complicated because the topic at hand is kind of complicated?
The proof that there are really no branches in git's storage is a simple task that's not achievable in git:
suppose you had some branch, but you don't remember it's name, then you branched off and issued some commits. Now there's no way to get a git history consisting of just the commits introduced since you branched off.
It is _exceedingly_ hard to lose files in jj, it's actually emotionally frustrating reading the line "most important thing [..] is to never ever delete file" because that's the whole shtick in jj with the oplog and whatnot - so something like nuking secrets completely from a jj repo is a bit of a chore.
Can you file a bug at least? A repro of some sort?. Or at least show us what is it what you did, `jj op log` might be enough to deduce what happened.
Also check out `jj op log -p`, your files might very well be in history, especially if, as you said, jj status took a long time (presumably snapshotting those files that got lost)
After 10 minutes, the person unfamiliar with Perforce, will not know how to deal with read-only files. No chance of that happening.
Because Mercurial was dreadfully slow at the time for anything as big as the Linux kernel tree. Linus also put his thumb on the scale because he was the author and still the primary maintainer of git at the time, so he could bend it to whatever shape he wanted without needing to ask anyone else. Not really a knock on Linus, I'd do the same in his position, but it does explain much of its advantage.
Having to add P4 support to any script, sucks. Having to do a network operation when touching files, sucks. Many many many apps have no idea what p4 is and will never get p4 support.
Git gets out of the way.
The other issue you ran into with ignored files becoming tracked is a known limitation. I agree that it's really annoying. We have talked about it many times before but we didn't have a proper issue for tracking it, so I created one now: https://github.com/jj-vcs/jj/issues/5596
A good git gui works as well as p4v (and usually far less buggy).
The major difference in my eyes is that p4 can enforce more settings from the server. It's easier to get artists set up in p4 than git.
> There's a reason that like 105% of AAA game dev uses Perforce.
Irony of ironies, Unreal is distributed with git but largely uses p4.
P4 is dominant but I feel like a lot of that is momentum. Making a Unity game with git is pretty easy. Some Unreal tooling is built around p4 only but not really for any technical reasons.
File locking is one of the reasons why vanilla Git is not that popular in game dev. It only exists with Git LFS and it is not really easy to use or reliable.
1) The fact that "fetch" doesn't happen automatically in the "chrome" commands.
2) naive use of "git merge" results in history that's a cyclopean horror. For example, caring about the "left" and "right" parents of a commit.
3) rerere isn't enabled by default so if you're merging from upstream constantly you're having to re-resolve same conflicts, every time is an opportunity to screw up.
4) a culture of keeping a clean history but cleaning history is destructive and painful for other users of the same branch.
5) git merge merges from local (stale) branch by default, so when merging from upstream to get new commits you have to remember to `git merge origin/main` instead of `git merge main`. Also see (1).
6) using submodules. At all.
Yes. I use it every day. I've ran P4 servers that serve hundreds of GBs per day globally with both commit edges and regular proxies. I've written batch scripts, bash scripts, and tooling in python, go and C# around it.
> Having to add P4 support to any script, sucks.
I disagree. It's no worse than adding git support to something. p4 zTag isn't the most elegant thing, but it works.
> Having to do a network operation when touching files, sucks.
Does it? Is it any worse than having to keep the entire history of every file locally on your machine, including any "large files?" And git-lfs as a solution to that means you're now coupled to wherever those files are stored. Making large submits to P4 isn't the nicest experience, but it sure beats paying that price every time you clone a repo IMO.
> Many many many apps have no idea what p4 is and will never get p4 support
In the same way that many people in this thread are blaming a git gui for a problem, "that's not P4's fault". I do agree it's shit though.
> Git gets out of the way.
Until it doesn't.
Losing your work should be exceptional. It's very, very easy to fuck a rebase up, and rebasing is (like it or lump it) a common operation. You shouldn't one step away from an exceptional case from a daily operation.
Git is complicated _beacuse_ of this. The defaults are tuned for this. But, most people don't need this. I'm sure there are people out there who set an upstream to their coworkers PC and clone a branch from them, merge it with their work and then someone else takes that and is saved a bunch of work because the commits all line up, but for every 1 of those people there are probably 100,000 who push and pull to a centralized forge, and pay the complexity cost for the distributed workflow.
> but they almost always fail to put forward some simpler alternative that can handle the same things. Is git actually accidentally complicated or purposefully complicated because the topic at hand is kind of complicated?
Git is complicated because it's got poor defaults, an unintuitive cli, and is designed for distributed workflows (I've never worked anywhere that has used a distributed workflow, fwiw). I can sit someone down with perforce for 15 minutes and basically never have to interact with them on it again. It's _so_ much simpler - because it's centralized. It has some baggage, is definitely not perfect (and it costs an absolute bomb). Mercurial is another example of something that is much, much easier to use and work with. I wish mercurial won, honestly.
[1] https://www.koyeb.com/blog/herokus-free-tier-legacy-the-shou... [2] https://blog.gitbutler.com/why-github-actually-won/
Right, but since git specifically was made for usage without decentralized servers, that complexity isn't accidental, it's purposeful as without serving that particular use case, git isn't really git anymore. Most design decisions in git comes from having to serve that use case, for better or worse.
> . It's _so_ much simpler - because it's centralized
Right, but that's also a poor comparison. A bit like saying that `mv` is much simpler than `rsync` because `mv` always move files locally. Yeah, that's true, but the entire point of `rsync` is to do remote sends/receives, so compared it to something that cannot, kind of ruins the comparison.
But yes it does literally include that. Perforce is THE standard tool for gamedevs. It’s not hard.
Now svn does have things I miss from the Mercurial world.. grep --all, fa --deleted, revsets, phases.. some could be implemented serverside in svn, but svn dev lost a lot of momentum post-DVCS (git esp).
But DVCS has issues that aren't an issue in svn land. History consistency, simple reliable narrow/shallow, people can work on files independently without syncing. (and a significantly more complex dvcs process)
With GitHub being the top platform for sharing source code and as the top choice for the basket of all our eggs, I'd wager we need DVCSs more than people need or appreciate today. And that's just considering how often GitHub is down today.
If we start to emphasize with people who have really shitty internet connections (which is a larger part of the world than you seem to think), we can start to understand why it's really useful to be able to share our code with our co-workers on our local network without having to rely on terrible, minimum 5s latency connections to US companies who basically don't care about you.
That's the thing. For most developers, it's not, and it doesn't. I have never needed a VCS that couldn't be wrapped in a few batch files like add.bat, get.bat, put.bat, diff.bat, merge.bat, and list.bat. You can do the same thing with git, of course, but just understanding enough about it to write the batch files practically takes a semester of study.
Unless your job is to maintain the Linux kernel, git is probably not the right tool for your job. But it 'won the source control war', so... git, it is.
Note: centralized does not mean you can’t work in offline mode or share basic deltas
Yes, network traffic does suck more than spending extra disk space, especially when you need multiple workspace because P4 sucks at switching anyway.
I don't understand what you mean about cloning. If you set up LFS properly it's not much worse than a fresh P4 pull.
But compare "git switch X" and "git restore X". This makes different things look different, and obvious, which is usually a valuable thing when learning a new tool.
in my 8 years of using git as a primary tool for vc, i have not once run into confusion on how to switch branches, create branches, prune branches, sync remotes with locals, and other common workflows.
does that mean i have only dealt with simple merges or haven't fucked something up bc i did not understand something and made things way harder than necessary (merging/replaying 50 commits vs squash rebase workflows, for example).
and no, you don't need to 'fetch' before you switch, fetching is only relevant if you're needing to bring in remotes or you're preparing for merges etc.
someone committing bunk to a main branch or something considered a production branch is not a git problem -- that's just bad development practices, and the onus is on the developer there to not do that and to understand why it is bad.
as for your other complaints, these are much more easily managed when the developers are not just arbitrarily commiting to branches without any strategic thought, but to point out, a lot of those problems are solved via working with commit hashes and branching, assuming you have already plugged the leak that is committing breaking changes to a main branch.
why are breaking changes that are mega changes even making it through to main?
you don't have to treat rebases or merges as this black hole of "i have no recourse for not getting it perfect the first time".