A small note: this will be much less organized and thought out than my other blog posts because I have been unable to convince myself to write a blog in about 2 years. Instead these are some notes to myself that happen to be public for anyone who finds them useful.
A small note written after spending 5 minutes on this post: holy shit this is so deranged I’m turning into Gankra lmao
big fan of the data model. not a fan of the UI.
Ok so before anything else, don’t panic. Your code is probably still there somewhere you just can’t find it. If you stop running commands right now, you can probably get it back.
I had a commit and then I checked out a different branch and now I can’t find the commit again 😭
git reflog, it shows you all the recent commits you were on.
someone told me to rebase and I did that but now git says “failed to push some refs”??? why is this happening
The error probably looks like this:
$ git push To github.com:jyn514/rust.git ! [rejected] simplify-storage -> simplify-storage (non-fast-forward) error: failed to push some refs to '[email protected]:jyn514/rust.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
This is totally normal. Git just gives absolutely awful error messages. Run
git push --force-with-lease and it should work fine.
Be careful using
--force. 99% of the time it works. The other 1% someone else pushed to your branch and you just deleted their work. They will not be happy.
wait but I ran git pull before I looked at your blog now what do I do???
Your latest commit probably looks like this:
commit 88fdea3dd2e876a92960601c019e729401e832ab (HEAD -> simplify-storage) Merge: d6bd3ef8662 6b22a42e011 Author: Joshua Nelson <[email protected]> Date: Fri Sep 2 19:24:33 2022 -0500 Merge github.com:jyn514/rust into simplify-storage
Get rid of it. We don’t want it. If you have changes since the latest commit, save them somewhere (e.g.
git reset --hard HEAD~. Now go to the step above about
I have a detached HEAD
WTF does that mean
You have turned into the Nick the Headless Horseman. Have fun trying to join the Headless Hunt.
No stop I came here for help
Git doesn’t think you’re on a branch or tag.
This is not the same as being on a commit that’s not in any branch or tag. It’s perfectly possible
to be on the same commit as the latest
main and still have a detached HEAD. It just means that
any new commit you make in this state won’t be on a branch.
How does this help me I don’t understand
Everything is fine. All your work is still here. You just need to figure out what you want to do next.
I don’t care about any of the work I’ve done in the last day I just want a git repo that works I will wipe this directory if you don’t help
DO NOT DO THIS IF YOU HAVE WORK YOU WANT TO SAVE!!!
git checkout --force $(git rev-parse --abbrev-ref origin/HEAD). If that gives an error for any reason try
git checkout --force origin/master or
origin/main instead. If none of those work IDK what to tell you maybe wiping the repo is the best idea after all. Good luck.
I have work I want to save please help me fix this I have a deadline in an hour
Ok. Pick which branch you want to put your work on. I’m going to pick
bark because branches have bark. haha
Does the commit you’re on have the work you want to save?
yes how do I get it to work
git branch --delete bark && git checkout --branch bark. This is the least invasive way to fix things;
whatever untracked code is in your working directory won’t be modified, and the old branch will still be in your reflog if you really need it. If you don’t know what that means, that’s ok, you’re on the right branch now and you can push it wherever you need.
no please I don’t know how I got into this state I really hate git right now
Figure out which commit has the work you want to save. Then run
git checkout <that commit> and then follow the steps about branches immediately above.
Git tells me something about “would overwrite untracked files”? idk what that means I just want to pull the latest branch
I’m going to assume the error looks something like this:
error: The following untracked working tree files would be overwritten by reset: src/tools/rls/Cargo.toml src/tools/rls/README.md Please move or remove them before you reset. Aborting fatal: could not move back to 9ba169a73acfa9c9875b76eec09e9a91cc6246df
There are three things I can think of that could be going wrong here:
- You made some changes and didn’t commit them. Commit them now. Go. Do it.
git add src/tools/rls && git commit.
This is in a submodule and git got confused. If you don’t know what a submodule is, mentally replace it with “code I have never modified and will never want to modify”. You can ignore this by running
git submodule deinit -f src/tools/rls(or whichever directory the submodule starts in - you can check with
git submodule status).
DO NOT DO THIS if you have made changes to that directory you want to save. Git will destroy all you hold dear. It is a sharp and powerful tool. You might call it … a subtle knife.
- This used to be a submodule and it’s no longer a submodule. You tried the
deinitthing above and it didn’t help. Try
rm -rf src/tools/rls. This does exactly what it looks like, don’t do it if you want to save your work.
If none of those fix it, glhf sucks to be you
I’m in rust-lang/rust and Cargo.lock keeps showing modifications but I definitely didn’t touch anything ???
yes this is a very specific problem. no I’m not going to take it out of the blog.
This happens because your submodules are out of date. Run
./x.py --help, which updates submodules for you.
Under the hood this is running the equivalent of
git submodule update --init --recursive which makes sure all the rust tool submodules are up to date.
that didn’t help.
sucks to be you
I made a commit and then I realized I want to make more changes but also people getting annoyed when I add lots of commits what do I do
First make your changes. Then run
git add .
If you want to change the latest commit you made, run
git commit --amend.
If you want to change an earlier commit, run
git commit --fixup <earlier commit> && git rebase -i --autosquash <earlier commit>~. Type the
~ literally but remove the
If you don’t know which commit you want to change, but you know it’s a commit you made since you made this branch, install
https://github.com/tummychow/git-absorb/ then run the
autosquash command from above. Absorb does magic to pick the right commits.
If you want to change a commit that’s already on master, don’t. Just don’t. If you’re really, truly convinced you need to, and you’re sure no one else minds (which in practice is probably never true), you can use https://github.com/newren/git-filter-repo.
I made a merge commit but now someone is telling me merge commits aren’t allowed how do I fix this?? please I already spent 3 hours on this I don’t want to spend 3 more
git rebase -i $(git rev-parse --abbrev-ref origin/HEAD) (or whatever your default branch is). Then go up to the bit about “failed to push some refs” above.
Yes this will probably cause conflicts. No I don’t know how to avoid that, probably some nonsense with
git reset $(git merge-base $(git rev-parse --abbrev-ref origin/HEAD)) && git add . && git commit or whatever. Don’t blame me if that doesn’t work, I didn’t test it. Also it throws away all the history, you keep the work but not the commit messages, you have to fish them up again with
git reflog or
git for-each-ref --sort=committerdate refs/heads/ | tail -n1 | cut -d' ' -f1 | xargs git log.
yeah no that’s it have fun kid
ok no actually one more thing —
can I talk for a second about how absolutely awful every error message I’ve quoted here is. they are so bad I don’t even refer to them when explaining what went wrong. half the time they point you to completely the wrong solution; the other half they give no indication at all of why something went wrong.
this is not how it should be. things can be better. here is an error message for the “push after rebase” that is actually useful:
$ git push To [email protected]:jyn514/rust.git (simplify-storage -> origin/simplify-storage) error: failed to push 1 commit to 'origin' hint: Both your current branch and the remote branch have changed since the last time you pushed changes. hint: The commits locally and in your remote have the same descriptions, and you just finished a rebase. hint: If you want to overwrite the commits on the remote, use 'git push --force-with-lease' to push. note: See https://git-scm.com/book/en/v2/Git-Branching-Rebasing for more information about rebasing.
See how that’s helpful? see how you understand more after reading it than before? unlike the absolutely useless error before
god ok that’s it for real I’m done now
update now that this is apparently popular
go read https://rustc-dev-guide.rust-lang.org/git.html too, it’s the most comprehensive document on rebase workflows that I’ve seen. no the official docs don’t count, if you don’t explain the common errors you run into it’s not comprehensive. also the manpages are useless unless you already know what the command does in which case WHAT WAS THE POINT OF THE MAN PAGE
also go read my twitter where you can read more nonsense like me complaining about how I can’t convince myself to go to sleep https://twitter.com/joshuayn514/