122 lines
3.2 KiB
Markdown
122 lines
3.2 KiB
Markdown
# git
|
|
|
|
A small command-line-like Git module for Racket, implemented directly on top of the `libgit2` package.
|
|
|
|
```racket
|
|
(require git)
|
|
|
|
(git 'status)
|
|
(git 'diff)
|
|
(git 'diff '--cached)
|
|
(git 'add "main.rkt" "info.rkt")
|
|
(git 'restore '--staged "scratch.rkt")
|
|
(git 'reset 'HEAD "--" "main.rkt")
|
|
(git 'grep '-i '-n "todo")
|
|
(git 'commit "Implement raco support")
|
|
(git 'tag "v0.2")
|
|
(git 'branch-current)
|
|
(git 'switch "main")
|
|
|
|
;; Display-oriented variant:
|
|
(dgit 'status)
|
|
```
|
|
|
|
`git` is an ordinary procedure; command names are symbols. `dgit` performs the
|
|
same operation, displays a compact human-readable result, and returns that result.
|
|
|
|
The same operations are available as normal procedures such as `git-status`, `git-add`, `git-commit`, `git-tag`, `git-current-branch`, `git-switch`, and `git-checkout`.
|
|
|
|
## HTTPS credentials
|
|
|
|
Version 0.2 adds persistent HTTPS credentials. They are stored in the
|
|
`racket-git.ini` file in Racket's preferences directory. Tokens are encrypted
|
|
with AES-GCM using a key derived from the store password with
|
|
PBKDF2-HMAC-SHA256.
|
|
|
|
Create the credential store once:
|
|
|
|
```racket
|
|
(git 'credentials 'init "store password")
|
|
```
|
|
|
|
Store a token for a Git host:
|
|
|
|
```racket
|
|
(git 'credentials 'set
|
|
"https://git.dijkewijk.nl"
|
|
"hans"
|
|
token)
|
|
```
|
|
|
|
The host is used as the credential key, so the same entry is used for all HTTPS
|
|
repositories on that host.
|
|
|
|
The store is unlocked for one day by default:
|
|
|
|
```racket
|
|
(git 'credentials 'unlock "store password")
|
|
```
|
|
|
|
or for an explicit number of seconds:
|
|
|
|
```racket
|
|
(git 'credentials 'unlock "store password" (* 8 60 60))
|
|
```
|
|
|
|
The temporary unlock state is stored in `racket-git-unlock.ini` in Racket's
|
|
preferences directory, so it survives restarting DrRacket and starting a new
|
|
Racket process. Both files are opened through `simple-ini` with `#:private? #t`; on Unix this
|
|
restricts them to mode 0600 before sensitive contents are written. The cached
|
|
derived key grants access to the credentials until its expiry,
|
|
so `racket-git-unlock.ini` must be treated as sensitive during that period.
|
|
|
|
Lock immediately with:
|
|
|
|
```racket
|
|
(git 'credentials 'lock)
|
|
```
|
|
|
|
After credentials have been stored and the store is unlocked, normal remote
|
|
operations use them automatically:
|
|
|
|
```racket
|
|
(git 'fetch)
|
|
(git 'pull)
|
|
(git 'push)
|
|
;; Example while a real push is in progress:
|
|
;; [git] push origin/main: compressing 45% (37/82 objects)
|
|
;; [git] push origin/main: sending 58% (48/82 objects)
|
|
|
|
;; Suppress network progress when desired:
|
|
(git 'push #:quiet #t)
|
|
```
|
|
|
|
## Supported Git operations
|
|
|
|
Version 0.2 supports repository discovery, init, clone, status, diff, add, restore, reset, grep, config,
|
|
commit, branch, branch-current, switch, checkout, merge, lightweight tags, log, remotes, fetch,
|
|
fast-forward-only pull, push, tag push, network transfer progress, and HTTPS username/token credentials.
|
|
|
|
SSH credentials, merge/rebase pull, annotated tags, and submodules are not yet
|
|
part of this module.
|
|
|
|
Install from the package directory with:
|
|
|
|
```sh
|
|
raco pkg install .
|
|
```
|
|
|
|
|
|
## Recover a detached HEAD commit
|
|
|
|
```racket
|
|
(git 'branch-current) ; #f
|
|
(git 'branch-create "rescue-readme")
|
|
(git 'switch "main")
|
|
(git 'merge "rescue-readme")
|
|
(git 'status)
|
|
(dgit 'log 5)
|
|
(git 'push)
|
|
(git 'branch '-d "rescue-readme")
|
|
```
|