Yeah learned this the hard way.
git reflog is your friend
The worst thing you could do is delete your local git repo.
Oi ya gits, everyone knows da best way to fix a mistake is ta smash it’s zoggin’ 'ead in!
Isn’t it the exact opposite?
If learned that you can never make a mistake if you aren’t using git, or any other way for having access to old versions.
With got it is really easy to get back to an old version, or bisect commits to figure out what exact change was the mistake.
The only way I understand this joke is more about not wanting to be caught making a mistake, because that is pretty easy. In other methods figuring out who did the mistake might be impossible.
You’re confusing errors in your code, and errors while doing some git command you thought you knew. Lucky you, it’s clearly never happened to you because you don’t mess around with it.
Sure, I sometimes messed up with git, but a git reset , checkout, rebase or filter-branch (In the extreme cases) normally fixes it, but real issues are very rare. And I use git a lot… But only the CLI, maybe people have issues with GUIs?
Funny those are commands I avoid… They all have to do with editing history which I know there is a vocal group here that loves “clean” history but that isn’t what happened.
sure merge full features so you can roll back a feature… And if something is really off I might start from a snapshot commit and cherry pick/merge a bunch in but usually history is histoy… If submitting to a public project I may make a new branch with the cleaned version but why edit in line. That is risking issues.
This is not about mistakes in the Tit-managed code. This is about mistakes in the Git commands themselves. Anything that involves merging/rebasing/conflict resolution can potentially be botched. These mistakes are usually fixable, but:
- Fixing it requires some Git proficiency behind the level of the common Git user.
- If you don’t catch it in time, and only find the mistake when it’s deep in your layers of Git history - well, good luck.
Went to tech elevator boot camp, was a decent experience even if I don’t find myself doing exactly what I was expecting to do. Life is that way though.
Anyways, my first week I fucked some git stuff up so bad I became the go to guy when anyone had any git issues because I had to learn so much to undo my egregious error. I don’t remember now exactly what it was but it took some serious git magic to sort.
Just saying that point 1 is very true. And yeah don’t make mistakes in git.
Hmm… I am using git for maybe 15 years… Maybe I’m just too familiar with it… and have forgotten my initial struggles… To me using git comes natural… And I normally pay a lot of attention to every single commit, since I started working on patches for the Linux kernel. I often rebase and reorder commits many times, before pushing/merging them into a branch where continuity matters.
Like accidentally committing multi-GB files and years down some poor mf (me in this case) has to figure out how to clear the files from history because the server is running out of space.
I just commit and push in the same line, all the time. Whenever I have to undo a change, I go to GitHub/Gitlab browse for the previous version and paste from there.
I definitely know is not the intended way to do this, but it works for me and has saved my ass several times.
And this is why mercurial is king. It just works.
- Use git for any code you write. Yes, even a simple script.
- Commit and push often. More often than you think is reasonable. You can always rebase / fixup / squash / edit but you can’t recover what you didn’t commit.
- ???
- Profit.
Seriously, once you commited something to the repo it’s hard to lose it. Unless you delete
.git
. But a this point frequent pushing has your back.I know git can be hard to grasp in the beginning. It was hard for me too. I highly encourage everyone to put in the effort to understand it. But if you don’t want to do that right now just use it. Just commit and push. It will pay off.
- (3) Get annoyed by constantly increasing Code Coverage Requirements on untestable (often legacy) code. Never down! Adding comments requires code coverage go up! Line must always go up!
- Change step 2 to “Commit and push ONLY when absolutely necessary. Because adding comments often requires a rewrite of untestable code.”
- Go back to Step 2 and wait for a major bug.
Our company “architects” decided we needed 80% coverage minimum. On a mostly .Net 4.8 codebase. Hundreds of programs used in prod, with barely any tests in sight.
It’s a fucking nightmare.Why would you care about code coverage requirements on a branch that is currently in development? My work in progress commits might not build because they don’t even compile, let alone have passing tests. The only time I care about the build passing and meeting requirements is when I’m ready to create the pull request.
Also code coverage is a useless metric, but that’s a different story.
Skill issue
With Jujutsu (which is compatible with git), you can just
jj undo
Can’t ya just git reset?
Anything you can do in Jujitsu you can do in git… The big difference is a paradime change:
-instead of a working directory that has pending changes you need to add than commit, all changes are in a commit that is lacking metadata.
The system has better “editing” of local history to set that meta data. But once you push to a shared repo you run the usual risks of force pushing.
I’m not sold, rather git not do anything until asked and just run git status constantly but I don’t have first hand experience… I would theory it would be more likely to add a file you didn’t mean to… Unlike those who use windows guis for git and forget to add new files.
That is so cool. Why doesn’t git have this already?
I mean, by definition, it does. It just involves parsing through the git log and a bunch of unintuitive, archaic commands.
Been using it for over a year now and not being scared of trying operations is such a boon. It helps so much with learning when you know you can just roll back to an earlier state.
Special shout out to the person who committed a gigabyte memory dump a few years ago. Even with a shallow clone, it’s pretty darn slow now.
We can’t rewrite history to remove it since other things rely on the commit IDs not changing.
Oh well.
Special shout out to the person who committed a gigabyte memory dump a few years ago. Even with a shallow clone, it’s pretty darn slow now.
If you want to be the team’s hero, I’ve had good luck removing old commits using
git filter repo
.https://hibbard.eu/erase-sensitive-files-git-history-filter-repo/
We can’t rewrite history to remove it since other things rely on the commit IDs not changing.
Oh right. Oof.
I would be working to arrange an accident for those other things. Those other things probably need to be retired.
The guy at work who managed git before me, well didn’t quite have the knowledge I do and was not using LFS. In one of the main repos a 200mb binary was pushed 80+ times. This is not the only file that this happened to. Even if you do a shallow clone, you still need to add the commit depth eventually. It’s a nightmare.
Sounds like a flawed workflow, if this didn’t go through at least code review. Was it committed directly to master?
Curious to know what kind of system relies on hashed not changing? Technically the hashes don’t change, but a new set of commits is made. The history diverges, and you can still keep the old master if you need it for some time, even cherry pick patches to it…
Why can’t you just remove the file?
Because the git history will still keep it completely to be able to restore it once you go to a commit in which it wasn’t deleted.
And you cannot tell git to completely forget about it as that requires a rewrite of history and this changes all commit hashes which are touched (and any future ones).
They most likely did in a later commit. However the commit adding it can not be removed as OP said. So in order for git to be able to work properly the file is still in the repository in case someone wants to check out a commit where it still was present.
“Shit, does this mean I have to re-install the operating system again. Fuck me!!!”
I have uttered this sentence too many times to count.
As long as you never touch the rebase button, you’ll be fine. Probably.
Even if you rebase you can still recover the original commits until they are garbage collected. You are generally safe as long as the
.git
directory isn’t deleted, in which case your whole history is gone anyway.Don’t be afraid of rebases, they are an essential tool in Git.
This particular fear can only be addressed by understanding.
I don’t understand it. Every time I see something about a rebase it’s some purist telling me it’s “cleaner”. Never got it to do what it says on the tin, and never hit a situation that I couldn’t solve using more straightforward tools like merge.
What’s your mental model for a Git commit, and a Git branch?
Once I properly learned those two concepts, understanding rebases became a lot easier.
I’ll try to explain it to the best of my abilities.
- Think of a commit being a patch - a description of how to take a particular file from one state to another
- A branch is a list of patches to be applied in order, from the point where the branch was created until the last commit on the branch
When you rebase a particular branch, what you’re essentially doing is taking all of the commits that are currently on your branch, checking out the other branch, and then applying each of the patches in order on that new branch.
A rebase can be cleanly applied if the premise for each commit has not changed when applied, but if the premise has changed, you get a conflict to be resolved before being able to continue the rebase.
I mentally model a rebase a bit as a fast version of how it would look like to build the branch I was on, but on top of the branch I’m rebasing on.
That’s a good explanation of what it’s supposed to do. That was how I understood it as well.
But anytime I’ve tried it, I’ve ended up with conflicts where there shouldn’t be (like, I already solved that conflict when I merged earlier) and/or completely undesirable results in the end (for instance, some of my changes are just NOT in the result).
So I just gave up on the whole feature. Simpler to just merge the source branch into mine.
Depending on how structured your commits have been, it can either be very difficult to get a rebase through or a complete breeze. There are some features to make it easier -
rerere
being the main one I’m thinking about.Is that what interactive rebase tools use?
I don’t do CLI git
…button
… and force push.
If you ever find yourself in a situation where rebase or a force push seems to be the solution, take a step back, clone your repo in a new directory and copy the changes into you’re new checkout - ‘cause you gon’ and screwed somethin’ up, son.
Force pushing is necessary when using rebases, and rebases are an essential tool, so you should not be afraid to force push under normal circumstances.
A few days ago I had to gently explain to someone why their rebase-and-force-push strategy not only prevented the use of “review latest” feature on GitHub, but was also pointless because all PRs are squash committed to main.
They didn’t get it and now they seem a little mad at me.
I’m guessing this is in reference to a scenario where a review of the PR has already been performed, and the rebase+force push is made to introduce new changes to the PR, possibly to address PR feedback.
I agree that these changes should be made in separate commits, for the benefit of the reviewer.
There are other scenarios where rebases are appropriate though, such as getting potentially incompatible changes from the main branch into the PR, and here I believe a rebase+force push is the right tool for the job.
Oh there’s totally a time and place for rebase strategies, this just wasn’t one of them.
Git’s biggest problems come from
people taking ritualistic views on what is “right” instead of thinking about which strategies work best for the situation, project, and team.
I rebase and force push daily. I like squashing all my commits, and our main branch moves quickly so I rebase off that often. Zero issues for me.
Same. And even if you were to fuck up, have people never heard of the
reflog
…?Every job I’ve worked at it’s been the expectation to regularly rebase your feature branch on main, to squash your commits (and then force push, obv), and for most projects to do rebase-merges of PRs rather than creating merge commits. Even the, uh, less gifted developers never had an issue with this.
I think people just hear the meme about git being hard somewhere and then use that as an excuse to never learn.
Why would you want to squash? Feels weird to willingly give up history granularity…
Because a commit should be an “indivisible” unit, in the sense that “should this be a separate commit?” equates to “would I ever want to revert just these changes?”.
IDK about your commit histories, but if I’d leave everything in there, there’d be a ton of fixup commits just fixing spelling, satisfying the linter,…
Also, changes requested by reviewers: those fixups almost always belong to the same commit, it makes no sense for them to be separate.
And finally, I guess you do technically give up some granularity, but you gain an immense amount of readability of your commit history.
Yeah, I hate it when my repo is a chain of merge commits. I want to see actual changes to the code, not branch management history.
I’m the opposite. I just let git take care of the stupid content. Why mess with the commit graph? Merging locally (instead of squashing) works better with merge requests because the graph clearly shows what changes went where.
I do some branch maintenance on my local branch (rebasing) until there are conflicts, but other than that I don’t see any benefit for messing with commit history.
I rebase and force push PR branches all the time. Master is moving quicker than my PR.
Never admit your mistakes. Always commit.
I don’t think you should be scared of git.
Unless by “scared” you mean “I pasted from ChatGPT and now I don’t know what to do,” in which case, please be more scared.
I have a full repo that mirrors any actual code I have, just so I can practice the very git operations with dummy files before doing it on a real codebase. It has come in handy many many times already and I highly recommend it.
git push origin main -f
You need to assert dominance
Until the user-based authorisation system of the server puts you in place.