A couple of quick tips. As you possibly know you can specify some options to be used for diffs (and other things) per file type. The one I'm interested in is the function name.
The primary way of identifying which part of an org-mode document
a change occurs in seems to me to be the heading. So, in your
$HOME/.gitconfig
put:
[diff "org"] xfuncname = "^\\*+.*"
Which should show any lines starting with one or more *
characters. And then in $XDG_CONFIG_HOME/git/attributes
or
$HOME/.config/git/attributes
put:
*.org diff=org
For anything that resembles lisp (so Common Lisp, Emacs Lisp, Hy,
scheme, etc.) I would think that the easiest thing to do is just
see the closes top-level form. So, in your $HOME/.gitconfig
put:
[diff "lisp"] xfuncname = "^\\([^ ]+ [^ ]+"
Which should show the opening parenthesis and the first two words. For example:
(defun some-function-name (defclass my-awesome-class (define-route this-strange-route
And then put in your $XDG_CONFIG_HOME/git/attributes
or
$HOME/.config/git/attributes
:
*.lisp diff=lisp *.el diff=lisp *.hy diff=lisp *.scm diff=lisp
And possibly any other lisp-like language files you can think of.
Sometimes you come across these gems of packages that seem to fulfill a wish that you didn't even realise you had.
Today I came across git-gutter for Emacs and its companion git-gutter-fringe, which are apparently based on an extension for Sumblime Text 2. These show the status of changes in a special "gutter" next to the fringe or in the fringe itself. This is very cool stuff.
To enable it I added the following code to my Emacs init file:
(eval-after-load "git-gutter" '(load "git-gutter-fringe")) (defun maybe-use-git-gutter () "Run `git-gutter' if the current file is being tracked by git." (when (eq (vc-backend (buffer-file-name)) 'Git) (git-gutter))) (add-hook 'after-save-hook 'maybe-use-git-gutter) (add-hook 'after-change-major-mode-hook 'maybe-use-git-gutter) (add-hook 'window-configuration-change-hook 'maybe-use-git-gutter)
git-gutter
was easily installed through MELPA, but I had to download
git-gutter-fringe
separately and use package-install-file
to install
that.
I had to load git-gutter-fringe
manually because it didn't seem to
have any autoloads defined, and I had to run it using these three
hooks because the information seemed to disappear if I switched
windows and came back, didn't automatically update after saving and
didn't automatically show anything when first loading the file. This
was all fine, since just calling the function updates the buffer it's
easy to use this way.
Later, though, I stumbled upon diff-hl by accident. I was looking for anything involving the fringe, which I think, for the most part, is underused.
It does pretty much the same thing, except that it does so at least for git, bazaar and mercurial (according to the readme). It also defines some commands for working with the blocks of changes, like navigating between them and reverting them. It uses the fringe by default, and doesn't require a separate package to be installed. And it's much easier to set up.
It can also be installed through MELPA, and afterwards it's just a line in our init file away:
(global-diff-hl-mode)
Of course if you don't want it enabled globally you can call
diff-hl-mode
from some hooks, but this way works fine for me.
It's funny how I had no idea these existed, didn't even think about needing/wanting this feature and then finding two of them in the same day.
Apparently there was something not going completely right with the mirroring of projects. I don't know why it seemed to work before, but now at least it seems that I'm an idiot and I can't write shell scripts (bash, zsh, sh, ksh, whatever…) to save my life.
Using a variable to store a command is not the way to go, I should have defined a new function.
Anyway, it is fixed again, seems I can mirror my beloved projects to github again.
A while back I found out how gitolite handles multiple users, by
reading the manual, whilst trying to figure out how to enable SSH
agent forwarding so I can semi-automatically mirror some repositories
to, for instance, github. I came to the conclusion that I had to
override the gitolite settings and add an extra line to my server's
authorized_keys
file. This seemed to work well.
Though apparently it didn't… I had noticed that I couldn't set any
options through the gitolite.conf
's config
commands, but I thought
this had something to do with not enabling the right settings to be
added. I was wrong about that…
I looked at my .gitolite.rc
on my server and saw that I had already
set GIT_CONFIG_KEYS
to ~'.*'~, so everything was allowed. I also
tested adding random config values to git locally, like
test.something
, which also worked; so it was neither git nor gitolite
that was causing the trouble.
I also noticed today that when I pushed changes to gitolite, at least
to the gitolite-admin
repo, that it was complaining about not being
able to fingerprint some file in /tmp/
. At that time I didn't think
the issues were connected, since I hadn't changed much lately and
pushing/pulling to my repositories seemed to go fine, apart from the
config values.
After some testing I noticed that I couldn't use any config values,
not even the gitweb.owner
setting which I was sure would work, since
I'd used that for every repo, but trying to reset them now didn't work
either. So I started looking on the server. It showed me the same
error as when I'd push to the gitolite-admin
repo plus a message about
the first line of something being too long, showing the beginnings of
a line in authorized_keys
.
After a lot of looking around, testing, screwing up my entire
setup and looking at the gitolite source on github, I think I figured
out what it's doing. Now, I don't know any perl, but is seemed to me
that it splits up the authorized_keys
file, checking the validity of
each line in it, except for the ones it put there. This is where it
was failing, since it would assume each line was just a public key and
could be verified by placing it in a temporary file and fingerprinting
that with ssh-keygen -l -f
, and I had the ~command="…"~ part in
there as well, to override gitolite's own settings to enable agent
forwarding. So now I know why it was complaining and why it was
always about line 1, even when I put my key on the last line in
authorized_keys
, but removing it would mean no ssh agent forwarding.
So I started looking at the gitolite source code again, trying to
figure out where those settings of no-X11-forwarding
,
no-agent-forwarding
, etc. were coming from and after a little while I
found it. Here I also saw that it was actually looking for the
AUTH_OPTIONS
rc setting. I don't remember reading anything about this
option, but then I'm still learning to navigate the gitolite manual.
Setting that to whatever was in my authorized_keys
file, but leaving
out the no-agent-forwarding
, fixed this latest problem.
So, now I've got my ssh agent forwarding and I can set any git config variable I want, which paves the way for writing a hook that will try to mirror a repository after receiving an update. This was certainly an interesting experience, and looking at some perl code was fun.
Oh, and I've also updated my gitolite installation, which now includes
a update-description-file
post-compile
trigger, which takes the value
from gitweb.description
and puts it in the description
file, so
programs like cgit can use it too.
I've been meaning to do two things for quite some time:
Write a utility for tracking the status of my various git
repositories.
Write a program in Guile scheme.
A few days ago I accomplished both and I named it gitto
.
It is a simple utility that allows you to register some repositories on your computer and it will list how many changes there are to push and pull, if the working directory is "dirty" and how old the last known commit on the upstream branch it, which it shows as last updated.
More details can be found here, including a link to the source. It requires at least guile 2.0.x and some version of git.
I still have to at least add docstrings and perhaps even a texinfo document, and I haven't released any version yet, but feel free to try it and be sure to let me know any suggestions/complaints/rants/bugs you might have or find.