Netatalk source code is now hosted in a shared git repository to which only Netatalk Team members are allowed to push into.
Links to Developer Ressources
- AFP Programming Guide
- AFP Reference Guide
- Inside Macintosh: Macintosh Toolbox Essentials Chapter 7 - Finder Interface
- Finder Interface Reference
- Technical Note TN1150 HFS Plus Volume Format
- CarbonHeaders source
- Mac OS X 10.6.2 source
- AppleSingle and AppleDouble v1 format internals
- AppleSingle/AppleDouble Formats for Foreign Files Developer's Note (version2)
- The git source code is available from http://www.kernel.org/pub/software/scm/git/.
- The project home page is located at http://git.or.cz/.
- You should probably familiarize yourself with the Git tutorial.
The examples in the following sections are based off of the tools and syntax used by git v1.5.3 or later. Either apt-get, yum, or make install the tools. See Git documentation for more details on this part. Note that under Debian or Ubuntu, git is distributed in the git-core package. The git package contains the "GNU Interactive Tools".
- the "master" branch is where development on new features is taking place
- branches named "branch-netatalk-x.y" for stable releases
- currently stable release branch branch-netatalk-3-1
- commits go to master (after a review, more on that below)
- commits can only go into a release branch if a bugreport exists
- the bugreport must be referenced in the commit message
- no branch merges
We now require formal review of all patches.
The author of patch should add a signed-off tag and the reviewer adds a reviewed-by tag. Very formal, but it encourages better coding and documentation.
This means every commit in master should have been reviewed by two team members (if the author is a team member, only one review by another team member needed).
This is the same process used in Samba
Commit messages should have a short, descriptive first summary line that begins with the affected component, eg
afpd: new options "force user" and "force group"
This is helpful when browing a git log in oneline mode.
Then the commit message should explain what the change is about, the more, the better.
At the end the author adds his signed-off tag.
Basic Netatalk Git
The master git repository is located at git://netatalk.git.sourceforge.net/gitroot/netatalk/netatalk. There is also a GitWeb installation.
Step Zero is to set your name and email address for commits:
$ git config --global user.email Your.Email@domain.com $ git config --global user.name "Your Real Name"
Next, clone the repository:
$ git clone git://netatalk.git.sourceforge.net/gitroot/netatalk/netatalk Initialized empty Git repository in /home/frank/test/.git/ remote: Counting objects: 31503, done. remote: Compressing objects: 100% (11427/11427), done. remote: Total 31503 (delta 24830), reused 25450 (delta 19869) Receiving objects: 100% (31503/31503), 6.52 MiB | 2.38 MiB/s, done. Resolving deltas: 100% (24830/24830), done. $ cd netatalk
List local and remote branches:
$ git branch * master $ git branch -r origin/branch-netatalk-2-0 origin/branch-netatalk-2-1 origin/branch-netatalk-2-2 origin/branch-netatalk-3-0 origin/branch-netatalk-3-1 origin/master
Creating your own working branch from master:
$ git checkout -b my_branch Branch my_branch set up to track remote branch refs/remotes/origin/develop. Switched to a new branch "my_branch"
Do your own local work:
$ mkdir git-test $ echo "hello" > git-test/README
View status of changes
$ git status # On branch my_branch # Untracked files: # (use "git add <file>..." to include in what will be committed) # # git-test/ nothing added to commit but untracked files present (use "git add" to track)
Add our new file to the local branch index:
$ git add git-test $ git status # On branch my_branch # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: git-test/README #
$ git commit -m "Example file for HOWTO" Created commit ad9a1eb: Example file for HOWTO 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 git-test/README
Do some more work and commit local changes....
Now fetch the remote branch history:
$ git fetch
To present your patchset properly to other developers, please rebase your patches against the branch you are developing against:
$ git rebase origin/master
Obviously replace "origin/master" by whatever branch you are developing against. If you have created a mess in your local patch queue, "git rebase -i" might help you out.
Assuming your patches are the last three commits on your current local git branch, this is the easiest way to create patches from them:
$ git format-patch -3
This will create three patch files in your current directory that you can then send to the samba-technical mailing list.
Note that if you have a number of patches against a specific branch and don't feel like counting them, the following works as well (e.g. against the develop branch):
$ git format-patch origin/develop
This will create one patch file for every patch that is in your local branch but not in origin/develop.
If you have more patches which belong together it's sometimes useful to export them into one file:
$ git format-patch --stdout origin/develop > develop-featureX-01.patches.txt
Debugging process crashes
We need a stack-backtrace (SBT) from a corefile with debugging symbols.
- Compile Netatalk with debugging symbols and without optimizations, eg for gcc
CFLAGS="-g -O0" ./configure ... && make && make install
- Enable global corefile generation (Linux, Solaris)
- Enable corefile generation for Netatalk by adding
ulimit -c unlimited
at the beginning of the Netatalk start script and restart Netatalk.
- Reproduce issue
- Get SBT (example for a crash of afpd and gdb):
$ gdb path/to/afpd path/to/corefile (gdb) bt full ... (gdb) exit
Since libatalk is now a shared library the autotools build system has been extended to do some ABI checking. A helper script abigen.sh is used to generate a symbol file containing all exported symbols of the dynamic libatalk library. These symbol files are named libatalk-VERSION.abi and are stored inside the libatalk source directory.
Every time make runs inside libatalk a symbol file libatalk.abi.tmp is autogenerated and checked against the current copy of the file matching the configured VERSION (as contained in the file VERSION). If there are any differences found, make aborts and the developer must update the symbol file and libatalk/Makefile.am library version info accordingly.
Making a release
Developers doing releases are expected to have a working understanding of the ABI checking infrastructure and must use the --enable-developer configure option.
- Bump VERSION
$ vi VERSION $ git commit -a -m "Bump version to x.x.x"
- Update NEWS as necessary:
$ vi NEWS $ git commit -a -m "Update NEWS"
- Re-run configure so the VERSION bump gets passed to the build system
$ ./configure ...
- Run make, this will create library ABI files
$ make clean && make ... make: Entering directory `/home/frank/netatalk/develop/libatalk' ********************************************************************************************************** created ABI file libatalk-3.0beta2.abi check https://sourceforge.net/apps/mediawiki/netatalk/index.php?title=Developer_Infos#ABI_checking ********************************************************************************************************** make: *** [all-local] Error 1 ... $ git status # On branch release-3.0beta2 # Untracked files: # (use "git add <file>..." to include in what will be committed) # # libatalk/libatalk-3.0beta2.abi nothing added to commit but untracked files present (use "git add" to track)
- Add ABI file to git and appropriate Makefile.am (eg libatatalk/Makefile.am for libatalk) ABI files
$ git add libatalk/libatalk-3.0beta2.abi $ git commit -m "Import libatalk-3.0-beta2 ABI file" $ emacs libatalk/Makefile.am ... $ ./bootstrap && ./configure ... (ensure the Makefile.am change takes effect) && make
This make run should now pass without error.
- Compare the ABI file to the previous version, verify VERSION_INFO, update Makefile.am version history
Update VERSION_INFO as necessary, update libatalk/Makefile.am version history. Note that VERSION_INFO info might already have been updated by the ongoing ABI checks by a developer when working on develop.
$ git diff @@ -28,6 +26,7 @@ VERSION_INFO = 1:0:0 # 3.0.0-alpha2 0:0:0 # 3.0.0-alpha3 0:0:0 # 3.0.0-beta1 0:0:0 +# 3.0.0-beta2 1:0:0 SUBDIRS = acl adouble bstring compat cnid dsi iniparser tdb util unicode vfs @@ -85,3 +84,4 @@ all-local: .libs/libatalk.so EXTRA_DIST = \ libatalk-3.0beta1.abi \ + libatalk-3.0beta2.abi
If you have to update VERSION_INFO again, commit the change, rebootstrap and configure.
- Run make distcheck, fix any errors
- Regenerate manpages from XML sources
$ make html $ git commit -a -m "Generate manpages from XML"
- Update and upload release notes:
$ cd doc/ doc/ $ vi www/ReleaseNotes doc/ $ git commit -a -m "Update release notes" doc/ $ USER=netatalk-sourceforge-adminuser make upload-release-notes
- Tag, release and roll tarballs
$ git tag TAG $ git push SOURCEFORGE-GIT-REPO TAG $ make dist $ make dist-bzip2
- Upload updates online manual:
$ cd doc/manual/ doc/manual/ $ USER=netatalk-sourceforge-adminuser make html-upload
- Reset VERSION to eg 3.0.8dev
Q. How do I revert a commit?
A. The "git reset" command allows you to reset the HEAD of the branch to any given point in history. To go back one commit, run "git reset HEAD^". This will keep your local changes and you can make any additional changes before re-commiting the new work. Also see the "git commit --amend" command and the "git reset" man page for other examples.
Q. How can I maintain a feature branch against the upstream Netatalk branches?
A. You clone the Netatalk repository as per the instructions above. Then you make a new feature branch:
$ git checkout -b feature_foo master
Now you do your development in your feature branch. Any time the master branch gets too different to the code in your feature branch you should rebase your feature branch. The rebase rewinds your feature branch to the point there it was branched. Then it updates you feature branch to the HEAD of the master branch and re-applies your changes.
$ git rebase master First, rewinding head to replay your work on top of it... HEAD is now at 357f003... Add WERR_SERVICE_ALREADY_RUNNING. ... Wrote tree 02299ef7c1cfa093248bfd9c6e3812805718845e Committed: e20a8c521d7860d9b7bd724ed5ea19c7306530ab
Rebase works best when you use it for local branches that are never pushed to a public repository, see Why won't "git push" work after I rebased a branch?.