venez ici

Articles taggés avec ‘Git’

3-way merge of Debian changelog files

Jeudi 8 octobre 2009

I’ve been considering for some time now to create a merge tool specifically suited for debian/changelog files. My goal was to let Git use it automatically thanks to gitattributes.

I’ve just gone ahead, so let me introduce you git-merge-dch. Grab it with git clone git://git.debian.org/~hertzog/git-merge-dch.git, you can build a package if you wish. Beware, you need to have a dpkg-dev 1.15.5 that is not yet published (so you need to build dpkg from its git repository, git clone git://git.debian.org/dpkg/dpkg.git) as I rely on features that I introduced recently… you will also need the libalgorithm-merge-perl package.

Using it in a git repository requires two changes:

  • defining a new merge driver somewhere in the git configuration (in .git/config or ~/.gitconfig for example):
    [merge "git-merge-dch"]
            name = debian/changelog merge driver
            driver = git-merge-dch -m %O %A %B %A
    
  • defining the merge attribute for debian/changelog files either in .gitattributes in the repository itself or in .git/info/attributes:
    debian/changelog merge=git-merge-dch
    

Now you can safely maintain two branches of a package with changelog files evolving separately and merge one into the other without creating undue conflicts. Suppose you created an experimental branch for version 2.28 (you use a version 2.28-1~exp1) when 2.26.2 was current stable in the master branch. In the mean time, 2.26.3 got out and was packaged in master. Next time you merge stable into experimental, the changelog entries for 2.28 and 2.26.3 won’t collide despite being at the same place in the changelog file compared to the common ancestor.

Let’s continue with this example, 2.28 is out. Instead of adding a new changelog entry with « New upstream release » without further changes, you keep the current changelog entry and simply change the version into 2.28-1. While preparing this you discover a branch with fixes that was based on 2.28-1~exp1, if you merge it it will reintroduce a 2.28-1~exp1 entry that you don’t want. Fortunately you can use the --merge-prereleases (-m) option of git-merge-dch so that it strip the prerelease part of the version string and considers 2.28-1~exp1 and 2.28-1 to be the same entry really.

The only limitation is that this merge tool will remove any lines which are not parsed by Dpkg::Changelog (and which in theory are not supposed to be there).

Feel free to test, share your comments, report bugs and send patches!

Git, CIA and branch merging

Lundi 7 juillet 2008

Dear Joey, we also had this problem for dpkg, that’s why I hacked the /usr/local/bin/git-commit-notice script that we’re using on Alioth to do something like this instead:

while read oldrev newrev refname; do
    branchname=${refname#refs/heads/}
    [ "$branchname" = "master" ] && branchname=""
    for merged in $(git rev-parse --not --branches | grep -v $(git rev-parse $refname) | git rev-list --reverse --stdin $oldrev..$newrev); do
         /usr/local/bin/git-ciabot.pl $merged $branchname
    done
done

It will stop git rev-list each time that it encounters a commit that is available in any of the other branches present in the repository and thus when you merge a branch, you only see the merge commit in CIA.

You should also note that the script is smarter as it calls CIA only for branch updates, not for tag creation (and other kinds of updates) where it only leads to strange errors IIRC.


Close
E-mail It