Git
Git⚑
Configuration⚑
New repo⚑
After running git init
:
git config user.name "[username]"
git config user.email "[email]"
git config user.signingkey "[key ID]"
git remote add origin [remote origin]
git push -u origin [branch]
Autosign commits⚑
Add the following lines to .git/config:
[commit]
gpgsign = true
Global .gitignore file⚑
git config --global core.excludesfile ~/.gitignore_global
Hooks⚑
pre-commit⚑
pre-commit/pre-commit is a framework for managing and maintaining multi-language pre-commit hooks.
Usage⚑
Skip specific hooks⚑
SKIP=no-commit-to-branch pre-commit run --all-files
Which is useful if a CI runs for the main branch so that it doesn't complain about running in it.
Merging⚑
Merge conflict style⚑
Take the pain out of git conflict resolution: use diff3
git config --global merge.conflictstyle diff3
After running this command to turn on diff3, each new conflict will have a 3rd section, the merged common ancestor.
<<<<<<< HEAD
GreenMessage.send(include_signature: true)
||||||| merged common ancestor
BlueMessage.send(include_signature: true)
=======
BlueMessage.send(include_signature: false)
>>>>>>> merged-branch
Usage⚑
Cloning⚑
Clone a repo and its submodules⚑
git clone --recurse-submodules -j8 [repo]
The -jN
option to fetch N
submodules at parallel.
For pulling the command is similar: git pull --recurse-submodules
Branches⚑
Create new branch and switch to it⚑
git checkout -b [branch name]
Delete branchs⚑
To delete a local branch: git branch -d [branch]
.
To delete a remote branch: git push origin --delete [branch]
Rename branch⚑
git branch -m [old_branch_name] [new_branch_name]
Fetch and track remote branches⚑
You need to create a local branch that tracks a remote branch.
git checkout --track origin/[branch_name]
Move last n commits to a new branch⚑
So you forgot to create a feature branch ah? No problem, let's move the last few unpushed commits to a new branch:
git checkout -b new_branch # create a new branch from the current one
git checkout old_branch # go back to the original branch
git reset --hard HEAD~3 # undo the last 3 commits
git checkout new_branch # go to the new branch and continue there
Commits⚑
Revert last public commit⚑
git revert HEAD
Revert public merge commit⚑
- Reset to the last good commit:
git reset [commit]
- Set everything as it was then:
git reset --hard
- Force push:
git push -f origin [branch]
Delete last commit⚑
git reset HEAD^
Note: this won't delete the changes made, just the commit. Also it will unstage the modified files.
Revert to a particular commit⚑
git reset --hard [commit-id]
This will remove local changes.
Reset file to specific revision⚑
To reset a file to its state in a specific commit:
git checkout [commit-id] -- [files...]
To revert changes made to a file in a commit (reset file to its version in the immediately previous commit:
git checkout [commit-id]~1 -- [files...]
Removing sensitive data from a repository⚑
If you commit sensitive data, such as a password or SSH key into a git repository, you can remove it from the history. To entirely remove unwanted files from a repository's history you can use git filter-branch
.
To force git to process the entire history of every branch and tag and remove the specified file as well as any empty commits generated as a result run:
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch {{path_to_file}}" \
--prune-empty --tag-name-filter cat -- --all
Note: If the file with sensitive data used to exist at any other paths (because it was moved or renamed), you must run this command on those paths, as well.
Modify specific commit message⚑
git rebase --interactive '<commit-id>^'
Then replace pick
with r
and save to modify the commit message.
GPG signed commits⚑
Sign last commit⚑
git commit -S --amend
Rewrite old commits⚑
Change last commit message⚑
To edit the message: git commit --amend
Then to push it to the upstream: git push --force
Change author username and email⚑
Create an alias in .gitconfig: change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$
echo $VAR\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "
Then from the repo:
git change-commits GIT_AUTHOR_NAME "old name" "new name"
git change-commits GIT_AUTHOR_EMAIL "old email" "new email"
Show commit information⚑
To see the information of a particular commit use:
git show <revhash>
Revert file to specific commit⚑
git checkout c5f567 -- file1/to/restore file2/to/restore
Files⚑
Untrack file/folder but keep locally⚑
It is a good idea to add the file/folder's path to .gitignore. Then, to remove the file/folder and its contents from git tracking: git rm [-r] --cached {path}
.
Tags⚑
Push tags⚑
To push the local tags to the remote server:
git push --tags
Tag current HEAD with a message and GPG sign it⚑
git tag -a [tag] -m "[tag message]" -s
Then, push it with: git push origin [tag]
.
Delete a tag local and remote⚑
git push --delete origin [tagname]
git tag --delete [tagname]
Syncing a fork⚑
Sync a fork of a repository to keep it up-to-date with the upstream repository.
git fetch upstream
git checkout master
git merge upstream/master
stash⚑
If you have uncommitted changes and you want to switch to another branch, you can temporarily save those changes with:
git stash
Then, to reapply them, do:
git stash pop
Log⚑
View file evolution⚑
You can use git log -L
to view the evolution of a range of lines. Example:
git log -L 15,23:filename.txt
means trace the evolution of lines 15
to 23
in the file named filename.txt
.
Diff⚑
Compare file accross references⚑
To compare a file accross references (branches, tags, commits...) do:
git diff <reference1> <reference2> -- <file>
Patches⚑
Create a patch⚑
To create a patch of the current unstaged changes:
git diff > patch.diff
Apply a patch⚑
To apply a patch:
git apply patch.diff
Or if you have it in your clipboard, just run git apply
and paste it.
Tips⚑
Unstage files⚑
git reset [file]
Debug⚑
Failed to delete remote branch (deletion of the current branch prohibited)⚑
The default branch must be changed from the web repo configuration.