GIT:
How to unfuck
Use GIT on the command line – useful hints
and how to undo common mistakes
https://www.flickr.com/photos/kalexanderson/5421517469/
Slide 2
Slide 2 text
If you already know something, don’t feel bored
– something new will come along!
If you are a beginner, don’t try to understand everything
– slides are online and can be used as cheat sheets
Personal style and experience, real life examples
– there’s more than one way to do things
Disclaimer
Slide 3
Slide 3 text
About Melanie
2011
Slide 4
Slide 4 text
“The command line is the only place
you can run all Git commands.”
https://git-scm.com/book/en/v2/Getting-Started-The-Command-Line
A new branch
git checkout -b git merge master
itty-feature
* big-feature
master
Slide 19
Slide 19 text
Going back in time
itty-feature
big-feature
* master
git checkout
git checkout HEAD
Slide 20
Slide 20 text
History
git log
--graph
--oneline
Slide 21
Slide 21 text
Don‘t lose your HEAD
Slide 22
Slide 22 text
references the commit
1 before HEAD
references to the 1st parent
of HEAD
history of movement of HEAD,
can be seen in git reflog
reattach HEAD to tip of branch
Don’t lose your HEAD
git checkout HEAD~1
git checkout HEAD^1
git checkout HEAD@{1}
git checkout
Slide 23
Slide 23 text
Reflog is your friend
git reflog
Slide 24
Slide 24 text
Moving the HEAD around
git reset --hard HEAD@{1}
git reset --soft HEAD@{1}
removes one commit and all work
– all uncommitted changes are lost forever
undoes one commit and puts the work from that
commit back in the workspace
Slide 25
Slide 25 text
When you
fucked up…
Keep calm and get help
Slide 26
Slide 26 text
Started working in master
Slide 27
Slide 27 text
Started working in master
git stash
git checkout
git stash pop
git commit –a
git push
or create a new one with “-b”, then you don’t
need to stash
Slide 28
Slide 28 text
Retrieving stash causes conflicts
Slide 29
Slide 29 text
Retrieving stash causes conflicts
git stash pop
git reset --soft HEAD
if there are conflicts when you run
“git stash pop”, Git will not drop the stash
Slide 30
Slide 30 text
Stash is super old
Slide 31
Slide 31 text
Stash is super old
git stash list
git stash show -p stash@{5}
git stash branch stash@{5}
shows content of stash
creates a new branch from the commit where
stash was created, checks it out and retrieves
the stash
Slide 32
Slide 32 text
Typo in branch name
Slide 33
Slide 33 text
Typo in branch name
git branch –m rename branch
Slide 34
Slide 34 text
Staged a file, but it needs to be ignored
Slide 35
Slide 35 text
Staged a file, but it needs to be ignored
git rm --staged removes file from tracking but leaves the file
untouched on disk
Slide 36
Slide 36 text
Typo in commit message
Slide 37
Slide 37 text
Typo in commit message
Slide 38
Slide 38 text
Typo in commit message
git commit --amend changes the last commit message
Slide 39
Slide 39 text
Forgot to commit a file
Slide 40
Slide 40 text
Forgot to commit a file
git add
git commit --amend uses the previous commit message
Slide 41
Slide 41 text
Undo all this amending
Slide 42
Slide 42 text
Undo all this amending
git reset --soft HEAD@{1}
git commit –C HEAD@{1} -C: reuse log message, author, timestamp
Slide 43
Slide 43 text
Delete the branch
Slide 44
Slide 44 text
Delete the branch
git branch –d
git branch –D
git push origin :
delete branch
force delete branch. Like rm -rf
also remote
Slide 45
Slide 45 text
Intermission
Coffee break for your brain
Slide 46
Slide 46 text
Committed broken code and pushed it
Slide 47
Slide 47 text
Committed broken code and pushed it
git revert
git commit
Creates a new commit that's the inverse of the
given hash.
Anything removed in the old commit will be
added in the new commit.
Anything added in the old commit will be
removed in the new commit.
Slide 48
Slide 48 text
Committed and pushed to wrong branch
Slide 49
Slide 49 text
Committed and pushed to wrong branch
git checkout
git reset --soft HEAD^
git stash
git checkout
git stash pop
git commit
git push origin
git checkout
git push --force origin
make sure you’re in the wrong branch
reset the branch back one commit
you will need to rewrite the message
force push commit deletion to original branch
Slide 50
Slide 50 text
Committed in detached HEAD
Slide 51
Slide 51 text
Committed in detached HEAD
git checkout -b
git merge origin
now you can push like in any other branch
adds current state of branch to latest changes
Slide 52
Slide 52 text
Don’t want to deal with merge conflicts now
Slide 53
Slide 53 text
Don’t want to deal with merge conflicts now
git merge --abort undo the merge and already resolved conflicts,
so you go back to your last commit
Slide 54
Slide 54 text
Need files from another branch
Slide 55
Slide 55 text
Need files from another branch
git checkout --
git checkout -- /*
copy file without merging
copy all files in folder
Slide 56
Slide 56 text
Need a single commit from another branch
Slide 57
Slide 57 text
Need a single commit from another branch
git checkout
git log
git checkout
git cherry-pick
returns list of commit hashes and messages
apply the changes introduced by this commit
Slide 58
Slide 58 text
Need changes from another branch,
but must not commit them
Slide 59
Slide 59 text
Need changes from another branch,
but must not commit them
git merge
git reflog
git reset --soft
git add -p
go back before the merge, but keep changes in
workspace
only commit your changes using patch mode
Slide 60
Slide 60 text
Don’t want to commit all changes in one file
git add -p
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?
patch mode
y - yes, stage this hunk
n - no, do not stage this hunk
? - print help
Slide 61
Slide 61 text
Accidentally used hard reset,
last commit is gone
Slide 62
Slide 62 text
Accidentally used hard reset,
last commit is gone
https://philna.sh/blog/2017/01/04/git-back-to-the-future/
git reflog
git reset --hard
shows moving to HEAD~1 plus last commit
Slide 63
Slide 63 text
Someone named branch like an existing file
Slide 64
Slide 64 text
Someone named branch like an existing file
git checkout
git checkout --
will checkout the file
will checkout the branch
“--” makes clear that the part is a branch,
everything after “--” must be a file path
Slide 65
Slide 65 text
Danger Zone
Changing history
Slide 66
Slide 66 text
Committed and pushed a password
Changing history
Slide 67
Slide 67 text
Committed and pushed a password
git filter-branch --force --index-filter
'git rm --staged --ignore-unmatch ’
--prune-empty --tag-name-filter cat -- --all
echo "" >> .gitignore
git commit -a
git push --force --all --v --dry-run
git push --force --all
git push --force --tags
git for-each-ref --format='delete %(refname)'
refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
removes specified file, as well as any empty commits as a
result, overwrites existing tags
add file to .gitignore
try it out first
collaborators need to rebase or check out anew
remove dangling commits
(after you’re sure everything still works)
Slide 68
Slide 68 text
Committed and pushed a password
Nuclear option
Slide 69
Slide 69 text
Committed and pushed a password
Nuclear option
rm
rm -rf .git/
delete repository and create a new one
git init
git commit .
git remote add origin
git push
remove all Git info from your code
manually on GitHub / Bitbucket / Gitlab etc.
push code to a new repository
Slide 70
Slide 70 text
My Git history is different from the one I pulled
git fetch origin
git rebase origin/master
git stash
git fetch origin
git reset --hard origin/master
git stash pop
delete folder and clone again
when someone else changed the history
when you have local changes you want to keep
when you prefer a clean slate
Slide 71
Slide 71 text
Configs
Have it your way
Slide 72
Slide 72 text
Bash prompt
.bash_profile
function parse_git_dirty {
[[ $(git status 2> /dev/null | tail -n1) != "nothing to commit, working directory clean" ]] && echo "*”
}
function parse_git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/[\1$ (parse_git_dirty)]/”
}
export PS1='\u@\h \[\033[1;33m\]\w\[\033[0m\]$(parse_git_branch)$ '
Configs
git config --global ...
core.excludesfile ~/.gitignore_global
core.editor “atom --wait”
merge.tool meld
commit.template ~/.gitmessage.txt
help.autocorrect 50
global gitignore, e.g., “.DS_Store” or “.idea/”
set Atom as editor for commit messages
set graphical tool for “git mergetool”
set default commit message, e.g., “WEB-”
accepts typos, e.g., “git pulll” (50 == 5sec)
Slide 76
Slide 76 text
Use the command line, Luke
Al says: commit early, commit often
Try not to push when you notice your error
Keep calm and almost anything can be undone
Takeaways
Slide 77
Slide 77 text
78
Slide 78
Slide 78 text
[email protected]
@mgapatrick
PHP developer
Admin and Core Tools Team
Melanie G. A. PATRICK
https://speakerdeck.com/mgapatrick/git-how-to-unfuck