2020-06-03 10:26:15 +00:00
# Tools
2020-10-07 19:46:34 +00:00
alias g="git"
2020-03-08 19:18:49 +00:00
2021-06-04 11:43:56 +00:00
y() {
2021-06-05 18:28:35 +00:00
unignore="$XDG_CONFIG_HOME/yadm/unignore"
test -r "$unignore" && cat "$unignore" | envsubst | yadm add --intent-to-add --pathspec-from-file=-
2021-06-04 11:43:56 +00:00
test "$#" -eq 0 && yadm s || yadm "$@"
}
2020-11-26 19:38:26 +00:00
yc() {
echo "config/$1:" >/tmp/yc-msg
yadm commit -v --template /tmp/yc-msg ${@:2} -- "$XDG_CONFIG_HOME/$1"
}
2021-06-06 16:37:36 +00:00
alias sy="sysyadm"
alias sysyadm="sudo yadm -Y /etc/yadm"
2021-07-13 10:14:58 +00:00
alias sysinit="sysyadm init -b main -w / && sysyadm gitconfig include.path '$XDG_CONFIG_HOME/git/config'"
2021-06-06 16:37:36 +00:00
2021-05-02 17:37:18 +00:00
gcn() {
if test $# -eq 0 || test -e $1
then
fulldir="$(realpath ${1:-$PWD})"
dir="${fulldir#$DATA/*/}"
else
dir="notes/$1"
fulldir="$DATA/2-standards/$dir"
fi
echo "$dir:" >/tmp/gcn-msg
git commit -v --template /tmp/gcn-msg ${@:2} -- $fulldir
}
2020-06-26 21:25:53 +00:00
# if in home or under XDG_CONFIG_HOME and not within a git directory, replace git by yadm
2020-06-08 09:42:34 +00:00
git() {
2020-10-08 09:11:51 +00:00
case "$1" in
2020-11-14 01:05:51 +00:00
reset) test "$2" = "--hard" && return 1;;
2020-10-08 09:11:51 +00:00
config) ;;
clone) ;;
*) case "$PWD" in
$HOME|$XDG_CONFIG_HOME|$LAST_YADM)
yadm "$@"
return
;;
2021-03-23 20:55:02 +00:00
$XDG_CONFIG_HOME*|$HOME/.local*)
2020-10-08 09:11:51 +00:00
if ! command git rev-parse --show-toplevel &>/dev/null; then
export LAST_YADM="$PWD"
yadm "$@"
return
fi;;
esac;;
esac
command git "$@";
2020-06-08 09:42:34 +00:00
}
2020-11-13 11:49:24 +00:00
# BRANCHES
2020-06-03 10:26:15 +00:00
# Remove list of tags local & remote
2020-03-08 19:18:49 +00:00
gitrmtag() {
2020-10-08 09:11:51 +00:00
declare -a refs
local index=1
for tag in $@; do refs[index++]=":refs/tags/$tag"; done
git push origin "${refs[@]}" && git tag -d "$@"
2020-03-08 19:18:49 +00:00
}
2020-06-03 10:26:15 +00:00
# Rename a tag
2020-03-08 19:18:49 +00:00
gitretag() {
2020-10-08 09:11:51 +00:00
git push origin refs/tags/${1}:refs/tags/${2} :refs/tags/$1 && git tag -d $1
2020-03-08 19:18:49 +00:00
}
2021-09-08 13:58:22 +00:00
# Open or select a project
2020-03-08 19:18:49 +00:00
project() {
2020-10-08 09:11:51 +00:00
cd $projects_dir
if [ -d $2 ]
then cd "$2" && gitorigin "$@"
else gitclone "$@"
fi
2020-03-08 19:18:49 +00:00
}
2020-06-03 10:26:15 +00:00
# Rewriting history {{{
2020-03-08 19:18:49 +00:00
# gets the AuthorDate of a given committish
git-authordate() {
2020-10-08 09:11:51 +00:00
local date=$(git log --pretty=fuller --date=raw -1 $1 | grep AuthorDate)
echo ${date##*: }
2020-03-08 19:18:49 +00:00
}
# executes a git command (usually commit) with the date of a given committish
git-withdate() {
2020-10-08 09:11:51 +00:00
date=$(git-authordate $1)
GIT_AUTHOR_DATE="$date" GIT_COMMITTER_DATE="$date" git "${@:2}"
2020-03-08 19:18:49 +00:00
}
# takes all changes in the current working tree and amends them to the given commit
gitedit() {
2020-10-08 09:11:51 +00:00
git stash
gitcommits -q $1
2021-01-03 14:01:11 +00:00
git reset --keep $1
git stash pop
2020-10-08 09:11:51 +00:00
git-withdate $1 commit --all --amend "${@:2}"
gitcommits
2020-03-08 19:18:49 +00:00
}
# takes two committishs and squashes them with all commits between them into a single commit
# this will rewrite the full history from then on, but should not create any conflicts
gitsquash() {
2020-10-08 09:11:51 +00:00
local -a options
while [ $# -gt 0 ]; do
case $1 in
-i) ignore=true; shift 1;;
-f|--force) force=true; shift 1;;
-*) options+=($1); exit 1;;
*) break;;
esac
done
((#!=2)) && echo "Usage: [options] <startcommit> <endcommit>" && return 1
[[ -n $(git status -s) ]] && [ ! $force ] && echo -e "Tree is dirty, commit or stash your changes first!\nIf you want to execute the command regardless, run again with --force" && return 1
1=$(git rev-parse $1)
2=$(git rev-parse $2)
[ $(git rev-list $1 --count) -lt $(git rev-list $2 --count) ] && t=$1 && 1=$2 && 2=$t
gitcommits -q $1
git reset --hard $1
if [ $(git rev-list $2 --count) = 1 ]; then
git update-ref -d HEAD
git add .
git-withdate $1 commit -c $1
else
git reset -q $2
git add .
git commit --amend
fi
gitcommits
2020-03-08 19:18:49 +00:00
}
# given a committish, this command saves a list of commits between the HEAD and the given committish into the .git directory
# when ran without parameters it applies the saved list of commits onto the current HEAD
gitcommits() {
2020-10-08 09:11:51 +00:00
verbosity=1
while [[ $# -gt 0 ]]; do
case $1 in
-v) verbosity=2; shift 1;;
-q|--quiet) verbosity=0; shift 1;;
--theirs) params=(-X theirs); shift 1;;
*) break;;
esac
done
stashed="$(git rev-parse --show-toplevel)/.git/stashed-commits"
if [ $1 ]; then
if [ $verbosity -eq 0 ]
then git rev-list --reverse HEAD...$1 >$stashed
else git rev-list --reverse HEAD...$1 | tee $stashed
fi
else
local aborted
for commit in $(cat $stashed); do
[ $aborted ] && rest+=($commit) && continue
[ $verbosity -gt 0 ] && git --no-pager log --oneline -1 $commit
git-withdate $commit cherry-pick $commit ${params:0} >/dev/null
last=$?
[ $last -gt 0 ] && aborted=true && typeset -a rest && continue
[ $verbosity -gt 0 ] && echo -e "\e[1A$(git log --color=always --pretty=format:"%C(yellow)$(git rev-parse --short HEAD^^)%C(bold) -> %Creset%C(yellow)%h%Creset %s" -1)"
[ $verbosity -gt 1 ] && git status -s
done
echo $rest >$stashed
[ $aborted ] && echo "A problem was encountered. Fix it and run 'gitcommits' again to apply the remaining ${#rest} commits."
fi
2020-03-08 19:18:49 +00:00
}
2020-06-03 10:26:15 +00:00
# }}}
# Testing
2021-02-16 12:08:56 +00:00
gittestcommit() { touch file$((++i)) && git add 'file*' && git commit -m "Create file$i"; }