Posts tagged git

Setting up Magit Forge with Github Enterprise server

:: emacs, git

I have attempted a number of times to create a pull request from the comfort of Emacs and Magit, with no success yet. The main problem is that I use most of the time my company’s GitHub Enterprise instance, not the public service called github.com. The GitHub service is so ubiquitous that many people forget there are other installations, not seen on the public Internet, where big corporations and hip companies keep their precious, precious code.

This week I finally made progress in setting up the connection.

Git setup with fork and upstream

:: git

Here is how to setup a fresh clone of a git repository so that it pulls changes from an upstream, but only pushes by default to another repository (usually, your own fork of the project).

I use the fish shell. If you use Bash or Zsh it should be straightforward to define these variables in your environment.

set gituser logc
set gitproject chat
set gitorg NacionLumpen

And this is how to setup the clone:

git clone git@github.com:$gituser/$gitproject.git
cd $gitproject
git remote add upstream git@github.com:$gitorg/$gitproject.git
git remote rename origin fork
git fetch upstream
git branch --set-upstream-to=upstream/master
git config remote.pushDefault fork

As always with git, it is trivial, if your name is ‘Linus’ :)

Some Git aliases

:: git

Here are some of the Git alias configurations that I use. My philosophy in writing them was to keep them descriptive, and not to keep them easy to type, following the approach in this blog post. In order to keep my typing short, I use the fish shell.

[alias]
	amend = commit --amend
	discard = checkout --
	docommit = commit --verbose --all
	hist = log --color --pretty=format:\"%C(yellow)%h%C(reset) %s%C(bold red)%d%C(reset) %C(green)%ad%C(reset) %C(blue)[%an]%C(reset)\" --relative-date --decorate
	lastedit = log --pretty=format: --name-only -n 1
	logshort = log --oneline -n 10
    lsmodified = diff --name-only head
	mkbranch = checkout -b
	rmbranch = branch -d

The aliases amend and discard are pretty self-explanatory. docommit reflects my own preferences when finishing a commit: just commit everything that is currently modified and add a diff under the commit message, so that I can review what I actually modified everywhere. hist is something I don’t use very much; I copied it from somewhere and I keep it around to avoid going to a GUI when I need to review history in-depth.

lastedit lists which files were edited in the last commit. I find it useful to just open them again in an editor:

$ vim (git lastedit)

logshort is probably the alias I use the most. It just gives me an idea of what was going on in a branch, without defaulting to show me all history since the beginning of time. lsmodified is a recent addition. It lists all files modified but not commited. It is intended to be used together with other aliases:

$ git discard (git lsmodified)

mkbranch and rmbranch are also quite useful to me. I tend to see Git as a file system: sometimes I start to type ls -l when I actually need git status. In that mindset, I tend to identify branches with directories, and therefore creating and deleting them as if they were directories makes sense.

Open files from last commit in Vim

:: vim, git

It is always a nuisance to remember which files were you working on when you last exited your editing session. I have tried different approaches, including:

  • leaving a test that does not succeed in order to get an errortrace that points to the next task I should tackle
  • opening the editor inside a tmux or screen session, and therefore never ending the editing session

The last idea I had was to create a unfinished Git commit (called “Unfinished: The commit title”), and use Git to retrieve the name of the files that were touched in that commit. You can do it like this:

$ git log --pretty=format: --name-only -n 1

If you alias that command in your .gitconfig, e.g. to lastedited, you can then open the files in your editor by command subtitution:

$ vim $(git lastedited)

Python egg tagged with Git commit hash

:: python, git

SVN

Python’s setuptools provide a simple mechanism to tag your built distributions with the SVN revision they belong to, by creating a setup.cfg file along the normal setup.py, and there write

[egg_info]
# Add svn revision to the file name
tag_svn_revision = 1

Git

How to do the same for Git? Or in general, with other information? (Date tagging is also supported by default).

Answer: modify directly the options dictionary in the call to setup, in setup.py. There, you can put anything you can compute with Python or system calls. E.g. for git:

import shlex
from subprocess import check_output

GIT_HEAD_REV = check_output(shlex.split('git rev-parse --short HEAD')).strip()


setup(
    # ... other keys like project name, version, etc ...
    options = dict(egg_info = dict(tag_build = "dev_" + GIT_HEAD_REV)),
)

With that setup, distributions (sdist or bdist) would be tagged with the string “dev” and the git hash of the latest commit:

$ bin/python setup.py sdist bdist_egg
$ ls dist
pyhello-0.1dev-92ffa06.tar.gz    pyhello-0.1dev_92ffa06-py2.7.egg

Whenever you want to build a stable release (without any “dev” tags), just set the key to empty in your setup.cfg, like this:

[egg_info]
tag_build =