posts tagged "git"

Some quick git diff tips

11 August 2013 0:54 AM (git | org-mode | diff | tips | magit | emacs | lisp | hy | elisp)

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.

For org-mode

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 lisp and lisp-like langauges

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.

highlight VC diffs

25 January 2013 2:20 AM (emacs | git | vc | diff)

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)

(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:


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.

Fixed it!

30 December 2012 2:59 AM (git | gitolite)

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, whatever8239) 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.

gitolite lessons

7 November 2012 3:19 AM (git | gitolite | config | ssh)

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't8239 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 that8239

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="8239"~ 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.


3 July 2012 2:25 AM (gitto | project | scheme | guile | git)

I've been meaning to do two things for quite some time:

  • Write a utility for tracking the status of my various git

  • 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.