October 24, 2021 15:16
HowTo Git
Nett2Know: Credentials
SSH-Key auth is heaven. You should use this. Really. If you commit and push a lot… You’ll NEED it. Also it is more secure than having a GitHub access token copy-pasted for every push. If you still need to use the HTTP-based remotes, you can configure the Git Credential Store. This will save the username/password as plain text to your disk - therefore only recommended when you must use Git LFS! To do that, just execute:
git config --global credential.helper store
…and every next HTTP-remote will only ask once for your credentials.
Setup
git init
Init of local repo
git clone
Gets remote repo with all branches and history
Run this to configure your profile (omit --global
for local repo only) - can also be modified inside .git/config:
git config --global user.name "[name]"
git config --global user.email "[email]"
Use the private repo mail (example: ID+DOMAIN+RND.USER@HOST), so nobody will get your private email!
Commands
Commit
git status
What branch is active? What are unstaged changes?
git add
/ git rm
Add / Remove files or folder (-> -r
) to the next commit…
git commit
Commit! (without a -m
nano will ask for more info)
git fetch
Gets the newest commits without applying them. Good for updating the log…
git rebase [branch]
Should be used after a fetch, this rewinds your commits and applies them after each other to the branch to rebase on. Therefore your commits stay on top of the history, instead of getting merged into their time-based slots (this will also not create a merge commit).
git pull
Gets the newest commits (fetch) and applies them (merge, this will also create a new “merge” commit). Note When you want to rebase instead of merge, just add --rebase
or execute git config --global pull.rebase true
- but note, that you can’t revert the merge this way anymore (as there is no merge commit to revert)!
git push
Pushes HEADs branch to remote (ether specify with origin [branch]
or on master directly it) - use -f
ONLY if someone has killed the repo / pushed to master directly!
git checkout -b [branch]
Creates a new branch…
git checkout --orphan [branch]
Creates a new branch, but with no histroy (not really useful, except in special cases)…
git merge [branch]
Checkout e.g. master and then run this to begin to merge of e.g. simon by using fast-forward-if-possible
git branch -d [killme]
Deletes a branch…
Working with the past…
git log
Shows the last commits (with the local/remotes branch HEADS position(-s))…
git checkout [existing branch / commit]
Update / Reset working directory to the histories point
Who has pushed directly to the master? AGAIN? / What-Have-I-Done-Edition
git diff [path]
Show the diff for a file
git blame [path]
Show the responsible author for every line.
F****
git reset [commit]
Two known usages:
- Add
--hard
to reset working tree AND history! So make sure not to have a detached HEAD - otherwise… Bye, bye history! - HEAD~n Move the HEAD n commits back (== revert commits without a “Reverting Commit”). This could mess up your ability to push the branch, as any new commit overwrites the remote history!
git fsck
Last chance before complete failure of the git folder structure. If problem persists: Wipe everything. Doesn’t work on most cases (like missing commit / history).
git gc
Cleans old, dangling commits from your disk (e.g. you ran git reset
and therefore disgarded some commits).
.gitignore
Add a path per line to get it ignored! The path is NOT absolute!
Change Authorname and Authoremail in history
- First time only (it’s global):
git config --global alias.change-commits '!'"f() { VAR1=\$1; VAR='\$'\$1; OLD=\$2; NEW=\$3; echo \"Are you sure for replace \$VAR \$OLD => \$NEW ?(Y/N)\";read OK;if [ \"\$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"\${VAR}\\\" = '\$OLD' ]; then export \$VAR1='\$NEW';echo 'to \$NEW'; fi\" $@; fi;}; f "
- Now you can use…
git change-commits GIT_AUTHOR_NAME "old name" "new name"
git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD
(you can omit theHEAD...
part) See here
If the credentials file has been added…
…or a file bigger than 100MB; or some private data has been commited - and already pushed: RESCUE IS HERE
Git LFS
…Imagine having a huge repository - lets say about 60 GB in files. But only some files are huge - lets also say they are all zip files. First activate LFS for your repo (don’t forget to install the git-lfs
package):
git lfs install
And specify which files you want to handle seperatly:
git lfs track "*.zip"
Thats it! Whenever you work from now on with e.g. GitLab this huge files will be compressed, downloaded only as needed and managed (much) faster!
Note: As stated on the GitLab help page the Git LFS authentication does not require you to setup the credentieal store mentioned before:
With 8.12 GitLab added LFS support to SSH. The Git LFS communication still goes over HTTP, but now the SSH client passes the correct credentials to the Git LFS client, so no action is required by the user.
Signed Git
As you may know, anyone could issue the git config user.*
command and therefore commit as-he-would-be-you. This is clearly not the best thing, but sometimes neccessary (e.g. while using rebase).
To clearly mark those impersonating commits, just use gits PGP functionality! And this is how it is done:
- Create a new key, either use the
seahorse
GUI or rungpg2 --gen-key
(make sure to installgnupg2
first). - Get the key id by either using
seahorse
again, or runninggpg2 --list-secret-keys --keyid-format LONG
(the id is behind thesec rsa.../
part) - Export the public key by running
gpg2 --armor --export [KEY_ID]
- you should upload this now to an public PGP key server, e.g. openpgp.org (this one verifies you are the emails owner and is also used inside Thunderbird). You could also use this key for signing (& encrypting) emails, messages, builds and much more! When you plan to use GitHub or GitLab, make sure to upload your key there aswell, as those systems do not use public key servers to download your public key automatically. - Enable git commit singing by executing
git config --global user.signingkey [KEY_ID]
and try to commit something usinggit commit -S
. - When this works, you may enable singing for all your commits from now on by running
git config --global commit.gpgsign true
.
Note You can always add more emails to your key or remove them. Also you can expire your sub-keys as needed, by just using seahorse
and then re-uploading your key to the keyserver.
Warning When you upload your key it is out there for all eternity! The key infrastructure is designed to ensure this! When you ever want to revoke a key you must have your revocation certificate!
To get it run gpg2 --output revoke.asc --gen-revoke [KEY_ID]
(seahorse
can’t do this for you) and then upload it as needed.
The commits are not getting signed and git only report errors after entering the commit message? Try to execute:
export GPG_TTY=$(tty)
Basic .gitignore
…for the most files from me - a more complete list is here…
# Netbeans
**/nbproject/
**/dist/
**/build/
.dep.inc
# (C)Make
**/CMakeFiles/
CMakeCache.txt
cmake_install.cmake
Makefile
# Kubuntu
.directory
# MacOSX
.DS_Store
# block directory for binaries
bin/
# Doxygen stuff
doc/
# CLion
.idea/
cmake-build-debug/
# Visual Studio Code
.vscode