note: access to remote repositories is managed via [[ authorized ssh keys | ssh key management ]] for the git
user on the remote host.
$ sudo adduser git
$ sudo su git
$ cd ~/
$ mkdir repositories
$ sudo su git
$ cd ~/repositories
$ mkdir project-name.git
$ cd project-name.git
$ git --bare init
$ git config core.sharedrepository 1
$ git config receive.denynonfastforwards true
$ find objects -type d -exec chmod 02770 {} \;
$ exit
$ sudo vi /etc/passwd
change the
git
user's shell from/bin/bash
to/usr/bin/git-shell
to disable, vice versa to enable.
$ git config --global core.excludesfile '~/.gitignore_global'
# vim buffers.
*.swp
*.swo
assuming you have a ~/.misc_envars
file, or something similar, that's sourced into your dotfiles, you can define functions like:
# some example variables.
export WEWLAD_NO="buTWhy?"
export COMMIT_SECRETS="w0uldYouDOThIs!?!!"
gconf_clientfoo() {
git config user.email "[email protected]"
}
gconf_clientbar() {
git config user.email "[email protected]"
git config user.url "https://github.com/look-a-client-specific-user"
git config user.signingkey oHB0ygpGS1gn3dC0mm1ts
git config credential.useHttpPath true # cloning via https, are we?
git config credential.helper osxkeychain
git config commit.gpgsign true # moar gee pah gee
git config pgp.program gpg # even moar gee pah gee
}
note: commiting secrets is a bad plan. it's a good plan to keep creds and project-specific git config functions in a seperate file, like ~/.misc_envars
and then gitignoring the .misc_envars
file. to use, clone a repo, move into it, then run the git config function of your choice.
this is essentially what a git alias is doing, except the git alias prepends what's in the single quotes with git
: for example
$ git config --global alias.clientfoo 'config user.email "[email protected]"'
is like gconf_clientfoo
function in ~/.misc_envars
. aliases work best for simple wrappers around git commands. for more full featured configuration, live off the land (bash).
$ cd project-name
$ git workprofile
$ cd project-name
$ git init
$ git add *
$ git commit -m “initial commit"
$ cd project-name
$ git remote add origin ssh://[email protected]/home/git/repositories/project-name.git
$ git push origin master
$ cd project-name
$ git checkout -b branch-name
$ git push -u origin branch-name
$ git branch --set-upstream-to=origin/branch-name
$ cd project-name
$ git fetch --all # sanity check.
$ git checkout master
$ git pull
$ git checkout branch-name
$ git pull
$ git merge master
$ git push origin branch-name
$ cd project-name
$ git fetch --all # sanity check.
$ git checkout master
$ git pull
$ git checkout branch-name # the branch you care about.
$ git pull
$ git rebase master
$ git diff # confirm expected changes, resolve conflicts, etc.
$ git push origin branch-name --force
typically, rebase
is used to groom git logs so those logs provide a more meainingful history of work on the project. this means that history is typically overwritten on a rebase, which means that a local working copy is going to diverge from the remote. in that case, --force
is required to overwrite the history on the remote to match the local working copy. this introduces a smaller margin for error, so measure twice and cut once.
$ cd project-name
$ git fetch --all # sanity check.
$ git checkout branch-name
$ git pull
$ git checkout master
$ git pull
$ git merge branch-name
$ git push origin master
$ cd project-name
$ git push --delete origin branch-name
$ cd project-name
$ git branch -d branch-name
note: useful for cleaning up when branches are deleted by cicd after merging downstream.
# handy function to drop in .bashrc/_profile/wherever.
git-prune-sync() {
if [ $# -eq 0 ]; then
local remote=origin
else
local remote=$1
fi
if [ "$(type -P git)" ]; then
git remote prune "$remote"
echo "pruned $remote branch references."
if git rev-parse --git-dir > /dev/null 2>&1; then
gone_remote_branches=$(git branch -vv | grep "gone" | awk "{print \$1}")
if [[ -z "$gone_remote_branches" ]]; then
echo "no local branches track a gone $remote branch."
else
for gone_remote_branch in $gone_remote_branches; do
echo "$gone_remote_branch" | xargs git branch -D
done
fi
else
echo "not a git repository."
fi
else
echo "'git' command not available. check your installation."
fi
}
$ git rm --cached file_or_dir
$ git commit --amend -chead
$ git push --force
$ git filter-branch --tree-filter "rm -rf file_or_dir"
$ git push --force
$ git reset --hard head~1
$ git push -f <remote> <branch>
$ git log # find the sha of the n-1 commit.
$ git rebase -i <sha of n-1 commit/> # note: will open vim, so if you're in vim already use fugitive.
# use the editor (vim) to squash (and possibly reword) commits.