Well well well.
Well well well.
Yeah learned this the hard way.
Well well well.
Yeah learned this the hard way.
Isn't it the exact opposite?
I 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 git 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.
This is not about mistakes in the Git-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:
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.
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.
Short of manually deleting .git you can always find any commit, you can walk backwards through your reference lof if it comes to it, the only real risk is throwing out unstaged changes.
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.
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.
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 is not related to using git in any way. I'm not really sure what you mean in 4. I didn't mean making a lot of changes, I meant that you should not wait with committing until you have a finished feature / fix / whatever. Commit after each refactor, commit after adding a new testable unit. It's always better to have more checkpoints. If your team does code review, they will appreciate atomic commits too.
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.
git reflog
git re-flog is what you do with those idiots who mess up the repo so that someone else has to come in and fix it again.
Reflog, when flogging isn't enough.
I hear people praise git reflog
a lot, but when do y'all use this? Most I've ever needed is git log --graph
for history checking. Maybe if I was in a situation where I knew the code on local branch X was working on Friday, but not anymore on Monday, then I could use git reflog
to go back to Friday for that local branch right? Is that the idea?
Power users rebase with squashes and fixups multiple times a day. Especially if the job’s integration process isn’t enforcing long living branches.
Reflog is useful then, because you literally rewrite history every rebase.
It’s not often, but a bad git reset, or a messed up rebase of that branch that’s 8 months old that you’ve picked up again.
I only use it when I've royally messed up and the commit I need to get back is no longer referenced anywhere. Accidentally deleted a branch, finished a merge or rebase before realizing I messed up, that kind of thing, just use the reflog to find it again, get a branch pointing to it, then try again.
git log
will only show you commits in your history. If you're only ever working forwards, this will contain all the stuff you'll ever need.
But if you're rewriting history, like with a rebase or squash or something, or you're deleting branches without merging them, then you can run into a situation where the official history of your branch doesn't contain some of the commits that used to exist, and in fact still exist but are unlinked from anywhere. So reflog is the log of where you've been, even if where you've been isn't in the official history anymore, so you can find your way back to previous states even if there isn't otherwise a name for them.
If all you care about is your current history, git can use the dates of commits just fine to see where you were on Thursday without needing the reflog.
When I'm not using git reflog
, it is only because I a'm not making big enough git
screw ups.
It's mostly for undoing a rebase or merge you're not happy with.
I really only need it when I done fucked up.
git reflog is your friend
The worst thing you could do is delete your local git repo.
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.
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..
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.
why did you merge 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.
With Jujutsu (which is compatible with git), you can just
bash
jj undo
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.
I've had zero issues with it so far and no one at work noticed anything different, other than there being a bit more rebase spam on PRs.
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.
idk but my dotfiles do:
alias undo="git reset --soft HEAD~1"
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.
Git repository operations are (almost?) always recoverable. git reflog
is your friend.
The filesystem operations are another story. Handle with care.
Wait, what does reflog do?
Think of it like your browser history but for Git. It’s a list of the SHAs related to your recent operations.
And because Git is a content-addressable data store, a SHA is basically like a URL. Even if a branch no longer exists, if you know the SHA it pointed to then you can still check out the exact contents of that branch. The reflog helps you find that.
You know... A version control system... That class of software that makes it possible for you to recover from any error you commit.
yeah, the whole thread is junior af
As long as you never touch the rebase button, you'll be fine. Probably.
Don't be afraid of rebases, they are an essential tool in Git.
This particular fear can only be addressed by understanding.
…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.
Hmm, I'm less afraid of force push. It does what it says on the tin. If I pushed a fuck-uo to remote and a reset is the simplest way out, you can bet I'm force-pushing that reset.
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.
I rebase and force push PR branches all the time. Master is moving quicker than my PR.
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.
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.
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.
Skill issue
Oi ya gits, everyone knows da best way to fix a mistake is ta smash it's zoggin' 'ead in!
Did they have a hose behind his head?
It's sweat
We need version control for the version control.
git gud, son
"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.
Never admit your mistakes. Always commit.
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.
And this is why mercurial is king. It just works.
I've had juniors who didn't believe this, so just to say it: If you know what you're doing, practically any Git problem is recoverable.
The one major exception is if you delete your local changes before committing them.
Yeah.But many of them are extremely annoying. Specifically screwing up rebase. It is recoverable, but very annoying.
That said I have seen juniors make two other common mistakes.
I'm fed up with these two. Yesterday I had to cherry-pick to solve a combination of these two.
Maybe I'm just a wizard, or I don't know what y'all are talking about, but rebases aren't special. If you use
git reflog
it just tells you where you used to be before the rebase. You don't have to fix anything, git is append only. See where the rebase started in reflog, it'll say rebase in the log line, thengit reset --hard THAT_HASH
Pushing without fetching should be an error. So either they got the error, didn't think about it, and then force pushed, or someone taught them to just always force push. In either case the problem is the force part, the tool is built to prevent this by default.
Continuing after merge should be pretty easy? I'd assume rebase just does it? Unless the merge was a squash merge or rebase merge. Then yeah, slightly annoying, but still mostly
git rebase -i
and then delete lines look like they were already merged?WDYM? Typically
git rebase --abort
will "just work". If you have specifically done something really wrong, just look intogit reflog
and thengit reset --hard
to whatever commit you were before the rebase.Git won't allow you to do that if you set up your server properly. It will force you to pull first. I have
[pull] rebase = true
in my settings so that it always rebases my commits instead of merging them, which makes for much cleaner history.This generally shouldn't be a problem, you can just rebase the branch afterwards and it will be fine (the common commits will typically just be dropped).
Is it ok to continue on a branch if you also merge back main into it? Like, branch gets merged into main on remote, local main pull, local merge main into local branch, push branch?
I’ll get chastised, but when I screw up a rebase I create a backup branch and then have an LLM do the fixing…
I’m not proud of it, but I’m a lazy man who doesn’t want to resolve the same conflict 32 times.
Fun fact! If you added a file but never committed it you can still recover it with
git fsck --lost-and-found
. The changes were still added to the git object store, and by grepping through the dangling blobs you can find the object containing the changes you care about.Does deleting the repo off disk and redownloading from remote considered recovering? If so I'm a git expert.
Delete? Never.
All hail the mighty reflog!
Saviour of us all!
o7
IntelliJ has local history for that case.
I’ve even recovered from deleting local changes I forgot how but there is a way! (It’s not something to rely on but can help in a pinch!)
Well, if you did commit it, but just hadn't pushed it yet, and then somehow lost that commit, then
git reflog
would be the tool for it.Without a commit, sometimes you may have already staged some changes for an upcoming commit and can roll back to that.
But if neither of those are the case, then I can't really imagine how Git should help you there. You haven't told Git about those changes yet, so it's out of scope.
At that point, you better hope your editor's undo history goes back far enough...