Ohh shit git! - Even I regularly exclaim this when trying to get work done with Git and Visual Studio. Many people coming from TFVC and other systems regularly bump into some crazy situations and need to figure out how to get back to usable state. Updated version presented at Bregler: https://www.bergler.nl/event/werken-git-praktijk/
6. Think ahead. Act now.
Ohh sh*t I made a typo in the commit message
git commit --amend -m “Centrum"
7. Think ahead. Act now.
Ohh sh*t I forgot to add a file to my commit
git add file2.txt
git commit --amend --no-edit
8. Think ahead. Act now.
Ohh sh*t I want to undo my change, but already
pushed it.
git revert <<commit>>
git push
9. Think ahead. Act now.
Ohh sh*t I totally messed up everything.
del /s /q /a /f .
git clone <your remote>
https://xkcd.com/1597/
10. Think ahead. Act now.
Ohh sh*t I totally messed up my repo and want to
keep my changes
Copy everything to a safe location
git clone <<your repo>>
git checkout -b fixbranch
Clear the folder
Paste the contents of your old repo (except the .git folder)
git add -A
git commit -m "Restored local changes!"
11. Think ahead. Act now.
Ohh sh*t I want to clean up my changes before I
share them
12. Think ahead. Act now.
Ohh sh*t I want to clean up my changes before I
share them
git rebase -i <<commit to start cleanup from>>
https://xkcd.com/1296/
13. Think ahead. Act now.
Why force pushing is BAD
It messes up the work of others
14. Think ahead. Act now.
Ohh Sh*t someone force pushed my parent
branch!
15. Think ahead. Act now.
Ohh Sh*t someone force pushed my parent
branch!
Not all is lost.
Try:
git pull –rebase
Or
git fetch origin/thatbranch
git rebase –onto origin/thatbranch
16. Think ahead. Act now.
Ohh Sh*t someone force pushed my parent
branch!
That failed huh?
Find the new hash <C> of the commit you last pulled
git rebase --onto origin/master <C> master
17. Think ahead. Act now.
A B C
master
D
origin/master
Local
A BX
master
Remote
Find B
18. Think ahead. Act now.
A B C
master
D
Local
BX
origin/master
Fetch origin/master
19. Think ahead. Act now.
A B C
master
D
Local
BX CX DX
origin/master
rebase --onto origin/master <B> master
master
21. Think ahead. Act now.
Let’s dig into reset
git reset --mixed (default)
• Move back in history
• Keep all changes in the working directory area.
git reset --soft
• Move back in history
• Keeps the working directory, has all the changes staged.
git reset --hard & git clean -df
• Move back in history
• Reverts all changes
• Removes all files and folders that are not tracked by git
22. Think ahead. Act now.
git reset --mixed B
A B C
Stagin
g area
Work
dir
master
A B C
Stagin
g area
Work
dir
master
23. Think ahead. Act now.
git reset --hard B
A B C
Stagin
g area
Work
dir
master
A B C
Stagin
g area
Work
dir
master
24. Think ahead. Act now.
Ohh sh*t I totally messed but my repo is still
working.
Go back to the last time you pulled
git reset –hard
Go back to a specific commit
git reflog
Find the last known good commit
git reset --hard <<hash>>
31. Think ahead. Act now.
Ohh sh*t I need to move more than one commit
32. Think ahead. Act now.
Ohh sh*t I need to move more than one commit
git log
Note the hashes you want to move
git checkout <<right>>
git cherry-pick <<oldest-hash>>..<<latest-hash>>
git checkout <<wrong>>
git reset --hard <<oldest-hash>>^
34. Think ahead. Act now.
A B C
E
right
wrong
D
C’ D’
git checkout right
git cherry-pick C..D
35. Think ahead. Act now.
A
B
= C^
C
E
right
wrong
D
C’ D’
git checkout wrong
git reset --hard C^
36. Think ahead. Act now.
Ohh sh*t I only need a single file from another
branch
37. Think ahead. Act now.
This is hard
Because git assumes commits, not files.
38. Think ahead. Act now.
Ohh sh*t I only need a single file from another
branch
I need the file as-is, ignore other changes
git checkout other-branch -- the-file-I-need.txt
I need specific changes from the other file
git checkout --patch other-branch -- the-file-I-need.txt
git cherry-pick <<hash>>
git reset --mixed
git add <<file to keep>>
git commit -m “cherry-picked one file” <<file to commit>>
git reset --hard
39. Think ahead. Act now.
Ohh sh*t I need to delete all references to a file
40. Think ahead. Act now.
Ohh sh*t I need to delete all references to a file
On linux:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch
filename' HEAD
On windows:
All examples are broken due to missing utilities, quoting issues,
powershell interference and other nonsense.
42. Think ahead. Act now.
Start with a fresh mirror clone
git clone --mirror git://example.com/some-big-repo.git
43. Think ahead. Act now.
Ohh sh*t I need to delete all references to a file
git rm <<file(s) to get rid of>>
git commit -m “remove safeties”
java -jar ..bfg-1.13.0.jar --delete-files <<files to get rid of>>
44. Think ahead. Act now.
Ohh sh*t I need to remove a password
git rm <<file(s) to get rid of>>
git commit -m “remove safeties”
java -jar ..bfg-1.13.0.jar --replace-text passwords.txt my-repo.git
45. Think ahead. Act now.
Then force your changes
git reflog expire --expire=now --all && git gc --prune=now –
aggressive
git push --all -force
git push --tags -force
46. Think ahead. Act now.
Important note
Services will not delete the object from their storage/database
To permanently get rid of the files for real:
CREATE A NEW REPO.
47. Think ahead. Act now.
It’s easy to make mistakes
And a 100 ways to solve them
Visual Studio doesn’t support them all…
48. Think ahead. Act now.
But we’ve seen it’s easy to
Fix the last commit
Revert a change
Move changes from one branch to another
Rewrite history
Make our co-workers miserable
Help them recover
As long as you know what you’re doing…