Skip to content

Instantly share code, notes, and snippets.

@jelmd
Last active March 10, 2020 16:25
Show Gist options
  • Save jelmd/0cec1d778f1202cd9a2eb7b39b655bbd to your computer and use it in GitHub Desktop.
Save jelmd/0cec1d778f1202cd9a2eb7b39b655bbd to your computer and use it in GitHub Desktop.
git hints
[user]
email = your_default@email_address
name = Your Full Name
[alias]
co = checkout
br = branch
ci = commit
st = status
#id = !git for-each-ref --format='%(refname:short) %(objectname:short) %(objectname)' refs/heads/master
id = !git for-each-ref --format='%(refname:short) %(objectname:short) %(objectname)' refs/heads/`git rev-parse --abbrev-ref HEAD`
outgoing = log origin..HEAD
incoming = log HEAD..origin
lg = !git log --graph --pretty=format:'%Cred%h%Creset%C(yellow)%d%Creset %s %Cgreen(%cd)%Creset' --abbrev-commit --date=relative --all
lgd = !git log --graph --pretty=format:'%Cred%h%Creset%C(yellow)%d%Creset %s %Cgreen(%cd)%Creset' --abbrev-commit --date=format:'%F %H:%M:%S' --all
info = "!git remote -v; printf 'Current:\\n '; git id ; echo 'Local branches:'; git branch; echo 'Remote branches:'; git branch -r"
rinfo = !git remote show origin
# file history
fh = !git log --find-renames --stat --follow
fhp = !git log --find-renames --stat --follow -p
# really throw away _all_ changes made so far
realclean = "!git clean -f -d; git reset --hard"
#d = "!git clean -f -d; git reset --hard; git co master; git branch -d check"
#a = "!git checkout $1; git checkout -b check"
[core]
pager = less -R
[branch]
autosetuprebase = always
[push]
default = simple
[gui]
fontdiff = -family \"Liberation Mono\" -size 12 -weight normal -slant roman -underline 0 -overstrike 0
fontui = -family \"Liberation Sans\" -size 12 -weight normal -slant roman -underline 0 -overstrike 0
# see http://git-scm.com/book/de/
# see https://guides.github.com/activities/hello-world/
# set fallbacks to use
git config --global user.name 'Your Name'
git config --global user.email 'your_default_email@address'
# git aliases:
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.id "\!git for-each-ref --format='%(refname:short) %(objectname:short) %(objectname)' `git symbolic-ref HEAD`"
git config --global alias.outgoing "log origin..HEAD"
#git config --global alias.outgoing whatchanged
# a 'git fetch' should be used before
git config --global alias.incoming "log HEAD..origin"
#git config --global alias.incoming "whatchanged ..origin/branch"
git config --global alias.lg "\!git log --graph --pretty=format:'%Cred%h%Creset%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative --all"
git config --global alias.info "\!git remote -v; printf 'Current:\n '; git id ; echo 'Local branches:'; git branch; echo 'Remote branches:'; git branch -r"
# pager (for ANSI color output) (we have LESS='-x4 -M -F -X' in the env):
git config --global --replace-all core.pager "less -R"
# I want to put my changes on top of what everybody else has done, i.e.
# having all their changes merged into local changes, so that the start of the
# change/branches point to the current HEAD/tip of it. So always use --rebase
# flag for "git pull" and avoid artificial merge commits and mimics
# git pull ; git rebase
git config --global branch.autosetuprebase always
# check:
git config -l [--global]
# clone a repo from github - NOTE, how "intentional" this crap is
git clone git@github.com:/${owner}/${repo}.git
# set a repo specific email
git config --add user.email your_repo_email@address
# diff zwischen 2 branches anzeigen (aus obiger liste auswählen, dabei das
# 'remotes/' prefix weglassen):
git diff origin/development..origin/development.ontohub.org
# diff zum unmittelbaren Vorgänger einer Revision
git diff HEAD^...
# diff zwischen zwei commits oder branches
git diff --minimal --color --ignore-space-change ${commitA}..${commitB}
# "letzte", d.h. noch nicht indizierte bzw. für den nächsten commit vorgemerkte
# Änderungen bzgl. letztem commit im aktuellen branch
git diff
# alle für den nächsten commit bereits vorgemerkte Änderungen bzgl. letztem
# commit im aktuellen branch
git diff --cached
# show changes made within a branch: $master == the branch, from which $branch
# got created (the node, where both branches split away). None of the branches
# need to be checked out, when doing this op. The upstream is 'origin/...', so
# $master could be 'origin/master' and $branch 'master', to see the changes
# within the local wrt. and the upstream master.
git log ${master}..${branch}
# logs nur für die commits im aktuellen branch anzeigen
git log origin/${branch}
git log ${branchA}..${branchB}
# show tree
git log --graph --oneline --decorate
# alle branches inkl. remotes anzeigen
git branch --list -a
# create a new local branch
git branch $bname
# create and checkout a new local branch in one row
git co -b $bname
# push out aka copy the local ${branch} to the origin (github)
git push origin ${branch}
# and automatically track this branch
git branch --set-upstream-to=origin/${branch} ${branch}
# history edit
# n == the number of last commits to merge - use 'squash'. NOTE that in git one
# must manually mv the 'pick' line to the top, otherwise git errors out with
# "Cannot 'squash' without a previous commit", even if all others are 'squash'ed
# =8-(
git rebase -i HEAD~n
# tag a certain commit
git tag patch_clean 3e4a923f3cb05e4ce3ce75bf1d6659bf743f2e8b
# check it
git show patch_clean
# sync wrt. deleted/orphan refs to remote branches (z.B. wenn 'git log' noch
# immer commits von einem bereits gelöschten remote branch anzeigt)
git fetch -p
# revert all staged and working directory changes like git {add|rm|mv} ...
git reset --hard
# remove all untracked files in the current directory
git clean -f -d
# remove the last commit to the remote repo's master
git push -f origin HEAD^:master
# create a [github release] tag
git tag -a -m 'original version + README.md and .gitignore' 'v2.5.0'
# push a certain local tags to the remote repo
git push origin $tagname
# push _all_ local tags to the remote repo
git push origin --tags
# recover a dropped stash if the terminal still shows the hash
# e.g. 'Dropped refs/stash@{0} (8b3555a1be9561db981ba28bf786d7fe9d07bb5a)'
git stash apply 8b3555a1be9561db981ba28bf786d7fe9d07bb5a
#============================================================================
# Workflow example (for local or "my own" remote feature branch)
#============================================================================
# merge all commits from ${branch} into ${master} branch
# branch an den HEAD des masters bringen
git co master # master branch auf aktuellen Stand bringen
git pull
git co ${branch} # lokalen "feature" branch auschecken
git rebase -i HEAD~n # optional: bei feature orientierter Entwicklung alles
# zu einem einzigen commit zusammenfassen, wenn
# angebracht und es nicht zu viel auf einmal wird
git rebase master # mit dem aktuellen Stand des masters abgleichen
git commit
git push origin ${branch} # falls ein remote branch der Ursprung ist
# mergen - sollte ein fast forward sein, da der branch ja auf gleicher Höhe
# mit dem HEAD vom master ist,
git co ${master}
git merge ${branch} # default: manual merge on conflict
# falls branch nicht mit master head gesynct wurde, gibt's i.d.R. merge
# conflicts. Wenn man nicht mergen sondern einfach file mit Konflikten einfach
# durch das einer Seite komplett ersetzen will
git merge -s recursive -X theirs ${branch} # branch überschreibt master files
git merge -s recursive -X ours ${branch} # ODER umgedreht
# und hochschieben
git push
# delete a local branch
git branch -d ${branch}
# delete a remote branch
git push origin --delete ${branch}
#===========================================================================
# Ausgechecktes aka non-bare repo per push aktualisieren
#===========================================================================
# auf remote-box repo auschecken, z.B.:
git clone ssh://${owner}@${host}/~/repos/${name}.git
cd ${name}
# das ist der Clou:
git config receive.denyCurrentBranch updateInstead
# dann auf der lokalen box das ausgecheckte repo hinzufügen
git remote add [--no-tags] ${repoAlias} ${repoURL}
# ab nun kann man wie folgt aktualisieren
git push ${repoAlias}
#============================================================================
# Workflow example (remote shared feature branch)
#============================================================================
# bei remote branches, in die von anderen Leuten auch rein-committed oder
# zwecks anschauen ausgecheckt wurde(n), ist ein rebase auf den master nicht
# so clever, da die anderen Leute dann auch rebasen, ihre lokalen Änderungen
# mergen und Index neu bauen müssen - menge Aufwand/Trouble. Deshalb werden
# hier einfach die inzwischen im Master einggegangenen Änderungen in den
# feature branch übernommen, und dann der branch mittels --no-ff in den master
# gemixt. --no-ff verhindert, daß die zuvor vom master "übernommenen" commits
# nochmal als "neue" commits eingehen.
# Phase 1: branch anlegen/Änderungen vornehmen
git fetch origin # updates vom original repo holen
git co -b ${branch} origin/${branch} # falls man selbigen noch nicht da hat
git co ${branch} # ODER falls er schon da ist co
# jetzt Änderungen vornehmnen und beliebig ins lokale repo comitten
git push origin ${branch} # lokale commits ins orig repo schieben
git merge master # mit master branch abgleichen, d.h.
# dessen letzte Änderungen übernehmen (Varianten: siehe oben)
# Phase 2: Merge branch into master
git co master # analog
git merge --no-ff ${branch}
git push origin master
#============================================================================
# Workflow existierendes repo mit anderem/fremden repo synchronisieren
#============================================================================
# z.B. das andere repo unter dem Namen 'upstream' im eigenen registrieren:
git remote add upstream git@github.com:${owner}/${forked_repo}
# check:
git remote -v
# Git-Daten ziehen
git fetch upstream
# localen Branch (z.B. master) auschecken
git co master
# ggf. log fom remote branch checken
git log upstream/master
# commits vom gewünschten 'upstream' repo branch (z.B. auch master) mergen:
git merge upstream/master
# lokalen branch, der z.B. auf dem master basiert auschecken
git co ${feature_branch}
# und ein rebase auf den master machen
git rebase master
#============================================================================
# Workflow existierendes repo woanders importieren alias verschieben
#============================================================================
# on the new site create the new repo, e.g.
git init --bare ${new_repo_name}
# after that, do on your machine:
git clone --bare ssh://${user}@${host}/~/repos/${name}.git bare_repo
cd bare_repo
git remote add new_repo git@${new_site}:/${owner}/${new_repo_name}.git
git push --all new_repo
git push --tags new_repo
cd ..
rm -rf bare_repo
# now one can remove the old repo, e.g.
ssh ${user}@${host} "rm -f repos/${name}.git"
# Fehler: You can't push to git://github.com/${owner}/${repo}.git
# Use https://github.com/${owner}/${repo}.git
# https:// ... geht aber auch nich (git Schwachsinn). Ergo URL anpassen:
# erstmal checken
git remote -v
# und nun ändern. Bei github ist prefix IMMER 'git@github.com:' !!!
# (siehe auch .git/config)
git remote set-url origin git@github.com:/${owner}/${repo}.git
# reduce the size of a git repo
git gc --aggressive --prune=now
# OR - according to Linus the better thing (but takes much much longer):
git repack -a -d --depth=250 --window=250
# continue an aborted svn clone
git svn clone http://svn.example.com/project/trunk project
# got signal 13
cd project
# repeat 'til finished
git svn fetch
# reset the local repo to see actually the files
git reset --hard
# convert a normal into a bare (master of the desaster) repo aka git server
# siehe http://git-scm.com/book/en/v2/Git-on-the-Server-Getting-Git-on-a-Server
mv $repo ${repo}.old
git clone --bare ${repo}.old $repo
#
git filter-branch --msg-filter 'sed -e "/^git-svn-id:/ s|http://www.virtualbox.org/svn/vbox/trunk|x://.|"'
#Rewrite $sha1 (1/55293)fatal: invalid date format: 0 +0000
#could not write rewritten commit
# git will Datum >= 1970/01/01 00:00:00 UTC +10^8s => 1973-03-03 09:46:40 UTC
Lokales repo nach primär Bitbucket "exportieren"
================================================
0) LEERES [privates] Repo auf bitbucket.org anlegen, d.h. ohne irgendwelche
Zusätze, wie generierte README*s, etc.
1) alte config ansehen und 'url' setting von '[remote "origin"]' merken
cat .git/config
# alternativ {Fetch|Push} URL merken von:
git remote show origin
2) URL des Hauptrepos ändern:
git remote set-url origin git@bitbucket.org:jelmd/snap-cam.git
3) optional: URL des alten Hauptrepos als alias hinzufügen
git remote add github git@github.com:jelmd/lbp.snap-cam.git
4) Und alles hochschieben
git push -u origin --all
Github repo initialisieren
==========================
# create repo $project on github
cd $project
make distclean
git init
git add .
git commit -m 'inital import'
git remote add origin git@github.com:jelmd/${project}.git
git push -u origin master
Branch umbenennen
=================
# branch lokal umbenennen:
git branch -m ${old_branch} ${new_branch}
# alten branch löschen:
git push origin :${old_branch}
# neuen branch pushen und tracken
git push --set-upstream origin ${new_branch}
# gitrevisions(5)
# Vorgänger Spezifikationen:
#===========================
#${X}^[n] ==> the n-th parent of $x (n==1 if omitted). Da nur merge commit mehr
# als einen parent haben, macht das auch nur Sinn für merge points.
#${x}~[n] ==> rekursive n-times: the first parent of $X.
#
# Der first parent ist der vorhergehende commit in dem branch, in dem man sich
# befindet/befand, als der merge eines anderen branches oder ein normaler commit
# ausgeführt wurde.
#
# Vorgänger Spezifikationen können durch Aneinanderhängen kombiniert werden.
#
# e.g.:
# A -- B -- C -- E -- G -- H
# \ /
# -- D -- F --
#
# G^ == G^1 == E ; G^2 == F
# G~2 == (G~1)~1 == E~1 == C
# G^2~ == G^2~1 == F~1 == D
# Range Spezifikationen:
#===========================
# .. ==> Alles commits die NICHT vom ersten Operand aber vom zweiten Operand
# aus erreichbar sind. Also im Prinzip Differenz zwischen {root,...,$OP2}
# und {root,...,$OP1}. z.B.:
# E..F => D,F bzw. F..E => C,E
# ... ==> Alle commits, die von Operand1 aber nicht von Operand2 erreichbar sind
# UND vice versa, also im Prinzip alle commits ab dem split point in den
# jeweiligen branches. z.B.:
# E...F == E..F + F..E == D,F + C,E == C,D,E,F
# tbd: https://hackernoon.com/lesser-known-git-commands-151a1918a60#.mzmz1r8t8
# Move last N commits from one branch into another
#=================================================
git reset --keep HEAD~$N
git checkout -t -b $newbranch_name
git cherry-pick '..HEAD@{2}'
# see https://stackoverflow.com/questions/1628563/move-the-most-recent-commits-to-a-new-branch-with-git/36463546#36463546
# Dump each commit of the repo as a single patch mail file
#=========================================================
rm -rf /tmp/x; mkdir /tmp/x
git format-patch -o /tmp/x -M95 --numbered-files --root
# and to read them in
cd /tmp ; rm -rf ast-open-jel ; git init ast-open-jel ; cd ast-open-jel
for (( I=1; I < 158; I++ )); do
git am /tmp/x/$I
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment