This workflow installs and configures GNU/Git, the decentralized
version control system.
Source Control
Requirements
- Git: distributed version control system
- GNU/GUIX: a functional package management system
- LitDoc: literate programming utility
Usage
To use this litdoc workflow, first download this file & build it.
guix ld build sc
To make git and associated codeberg-cli available in
the current shell use,
guix ld sc
To load Emacs integration, run M-x workflow-select
within an Emacs session. Then follow the on screen
prompt and select sc.
Dependencies
This workflow installs git from the official GNU/Guix repository.
(specifications->manifest (list
"git"
"git-lfs"
"codeberg-cli"))Shell Integration
Shortcuts for quickly collecting git repository information.
gr: show full path to the root of the current
git repository(if any).
gr(){
git rev-parse --show-toplevel $@
return $?
}
gg:shortcut to git status
gg(){
git status
}
gl:show git log of the current repository.
gl(){
git log $@
}
gu:undo last git commit
gu() {
git reset --soft HEAD~1
}gun:undo the last N git commits,
gun(){
git reset --soft HEAD~${1:-1}
}
signoff:sign-off the last git commit of the
current repository
singnoff(){
git --amend --sign-off
}Emacs Integration
Customization
Enable/Disable Emacs integration with forejo based code hosting
(defcustom sc:enable-forgejo-integration t
"Forejo integration enable or disable(nil)"
:type 'boolean)When forgejo based code integration is enabled, this variable
can be used to define the host base URL. The default value
is codeberg.org.
(defcustom sc:forgejo-host "https:://codeberg.org"
"Forgejo instance host URL"
:type 'string)Keybindings
Emacs Key Bindings
(kb::def :states 'normal
"g" '(:ignore t :which-key "git")
"gs" '(magit-status :which-key "status")
"gl" '(magit-log :which-keu "log"))Forge
(when sc:enable-forgejo-integration
(kb::def :states 'normal
"g#" '(magit::forge-push :which-keu "forge push")))Packages
Package: magit
magit is the de-facto standard for integrating git with Emacs.
(use-package magit
:guix (:name emacs-magit)
:config
(message "magit config ready!")
:commands
(magit-blame-mode
magit-commit
magit-log
magit-status)
:general
<<magit-kb>>)
magit extension for working with Forge based hosts such
as https://codeberg.org:
(use-package agitjo
:guix (:name emacs-agitjo)
:after magit
:init
(defun magit::forge-push ()
(interactive)
(require 'agitjo)
(agitjo-push))
:commands
magit::forge-push
:config
(agitjo-setup "#"))
Package: forgejo
Front-end for codeberg.org and Emacs integration
(use-package forgejo
:guix (:name emacs-forgejo)
:commands
forgejo-vc
:custom
(forgejo-hosts '(("https://codeberg.org")))
;; Example watch rules
(forgejo-watch-rules
'(("thanosapollo/emacs-forgejo")
("guix/guix" . "state:open label:team-emacs")
("*" . "author:<your username>")))
(forgejo-watch-filter-default "read:no"))forgejo-vc
Application Notes
Git Workflow
The key to using git is crafting a good commit. A good commit should do one thing concisely and has to leave the repository in a working state. That's about it.
Commit Messages: the subject-line should describe what changed and why the change was introduced in 50 chars or less. And prefer imperative forms when possible.
if commit is applied, then [insert commit subject-line] – This should make real good sense
Git Workflow? All things being equal, choose the simplest workflow. The forking workflow is one example See Forking workflow .
SSH Access: enable SSH protocol with git remote set-url
command:
git remote set-url origin [git@coffee.hub.com:user/path.git]
If you have not already setup an SSH key, one can be generated
using the ssh-keygen command.
mkdir -p ~/some/personal/directory
pushd ~/some/personal/directory
#create two SSH keys for the sake of demonestration
ssh-keygen -t ed25519 -C "me@workforcofee" -f "${HOME}/.ssh/coffee"
# => ~/.ssh/coffee.pub, public key
# => ~/.ssh/coffee, private key
ssh-keygen -t ed25519 -C "me@workforbeans" -f "${HOME}/.ssh/beans"
# => ~/.ssh/beans.pub, public key
# => ~/.ssh/beans, private key
# Register the keys on this machine
ssh-add coffee
ssh-add beans
Add the generated keys to ~/.ssh/config
Notice, to unregister a given key-file you can run
ssh-add -D ~/.ssh/coffee
Host coffee.hub
HostName coffee.hub.com
User git
IdentityFile ~/.ssh/coffee
Host git.beans
HostName git.beans
User git
IdentityFile ~/.ssh/beansPatch Workflow
Problem working in a code base, maybe big and complex like Emacs, and you want to make small modifications, patches, to each release or update with minimal merge conflict related issue.
Solution keep each patch simple and independent. Place each patch into its own branch.
That is, first get a fresh copy of upstream updates. Switch to a new branch to be used for the patched codebase.
git checkout -b tracking git pull orgin main
Merge each patch branch one at a time and use --no-off option to help
keep branch history. If there is a merge conflict, since each patch is small
it should be much easier to address.
git merge --no-ff patch1 git merge --no-ff patch2 git merge --no-ff patch3
Test the tracking branch & finally merge it to the main branch.
Signing Commits
Git supports signing and verifying work, commits and tags, using GPGsn:]].
Select GPG Key: For the sake of simplicity assume there is one or more GPG key availablesn:]].To select from a list of available keys run,
gpg --list-keys --keyid-format long
pub <PRIMARY-KEY-INFO>/<KEY_ID> <CREATE-DATETIME> [SC] [expires: <EXP-DATETIME]
<FINGERPRINT>
uid <USER-INFO> <EMAIL>
sub <SUB-KEY-INFO>/<SUBKEY-ID> <CREATE-DATETIME> [E] [expires: <EX-DATETIME>]
Take a note of <KEY-ID> and make sure the key is
tagged with [S] which stands for signing. For example
if the key is marked with [E], that means it can only
be used with encryption.
Configuring git: add the selected <KEY-ID> to git
configuration(.git/config).
git config user.signingkey <KEY-ID>
git config gpgSign trueAdd GPG Key to Gitlab: add the public GPG key to Gitlab to enable commit verification following their guide. The public key can be generated using,
gpg --armor --export > gpg.public.txt
Signing Commits: once configured git commits and tags can be signed off using the
--sign-off or its short form -S option,
git commit -S -m "commit description"Also, git log --show-signatuers can be used to verify commits were
signed off properly.