Git guidelines

Patches to the original source code

Debian patches to the package original source must be stored in debian/patches directory. Debian patches are applied when the package is built and unapplied when the package is cleaned. The package uses quilt [1] for managing those patches. Various tasks of patch management (adding, removing etc.) are described in /usr/share/doc/quilt/README.source (provided by quilt package of version 0.46-4.1 or later).

Public VCS repository of Debian packaging

Debian packaging history of this package is stored in Git [2] repository. Repository policy and packaging workflow are described below. This information is mostly for Debian package maintainers or people following packaging process. If you are merely preparing a NMU which changes upstream code, feel free to follow a standard patch creation procedure with quilt as described in the section above.

Pushing permissions and occasional contributions

Committing policy and guidelines

See our standard style for changelog entries for more information.

Branching policy

Debian packaging branches must not contain original source and must not have been merged with a branch containing original source code (referred by name "upstream" in the rest of this document) in any point of their history. If necessary, it is recommended to keep a private upstream branch in the private local repository or just track upstream remote Git repository locally. Debian packaging branches must only contain debian/ subdirectory in their root directory in order to avoid potential conflicts with upstream source. This restriction applies even to Git-specific files like .gitignore.

Branches should be named as follows:

Non-fast-forwarding pushes (e.g. rebase of already published history) are forbidden to all mainline packaging branches unless they are absolutely necessary and have previously been agreed upon by co-maintainers of the package.

Tagging policy

Tag namespace "debian" is reserved for tagging package releases to Debian. Preferably, public repository should not contain any other tags unless otherwise agreed upon. Each official package release must be tagged. The tag must meet the following requirements: For example, in order to tag the tip of current packaging branch as upload of the package version 4:4.6.0~beta1-1 to experimental, the following command may be used:

  $ git tag debian/4.6.0-beta1-1 -sm "4:4.6.0~beta1-1/experimental"

Versioning of upstream snapshots

Since Git commit IDs are not sequential, it is recommended to use a sequential number (number of commits since the latest tag) that `git describe` returns at the tip of the upstream snapshot being packaged. For example, if:

  $ git describe
  v1.2-beta1-45-67890abc
then Debian package upstream version part of this snapshot could be 1.2~beta1+git45+67890abc.

Cloning public packaging repository

For users with ssh access to alioth:

 $ git clone git.debian.org:/git/path/to/the/remote/repository.git

For anonymous users:

$ git clone <Vcs-Git URL from debian/control>
Wait a bit. You will end up with full clone of the public repository and a local branch master will be setup to track remote master branch (origin/master). Change to the directory of the repository. In order to track another packaging branch (e.g. lenny) locally, run:

$ git checkout -b lenny origin/lenny
Now let's setup `git push` to push all packaging branches and debian tags by default:

    $ git config --add remote.origin.push "refs/heads/master"
    $ git config --add remote.origin.push "refs/heads/lenny"
    $ git config --add remote.origin.push "refs/tags/debian/*"
    

Pulling changes

In order to avoid pointless merge commits, it is recommended to use --rebase option to `git pull` when pulling changes from the remote repository if your local master contains not-yet-pushed and rather trivial commits:

  $ git checkout master
  $ git pull --rebase
  

Integrating original source into local repository

Obviously, packaging process requires to have original source next to the debian/ directory. Since it is not allowed to ship upstream source in the public packaging branches, it needs to be retrieved and managed outside packaging branches. Basically, there are a couple of options:
  1. Original source is extracted to the packaging branch working tree from the tarball:

           # (only once) Ignore everything (upstream source) but files under debian/.
           $ git config core.excludesfile debian/upstreamignore
    
           # Checkout a packaging branch
           $ git checkout master
    
           # Remove all untracked files including ignored ones. This cleans up the
           # root directory from old upstream sources (if any)
           $ git clean -xdff
    
           # Extract upstream source code into packaging branch working tree
           $ tar zxvf ../qt4-x11_4.5.2.orig.tar.gz --strip=1
    
           # Do packaging, committing, finally push...
         
  2. Original source is maintained in the separate (local) branch(es) and is read into the packaging branch as needed:
    1. If original source comes in the form of the tarball, it can be maintained in the local 'upstream' branch. When creating such a new disjoint upstream branch, execute:

                # Switch HEAD to not-yet-created upstream branch
                $ git symbolic-ref HEAD refs/heads/upstream
              
      When updating an existing upstream branch to a new release, just do:

                # Clean current branch before checkout
                $ git clean -xdff
                $ git checkout upstream
              
      Then do something like this:

                # Remove all tracked files (e.g. old sources)
                $ git rm -r '*'
      
                # Extract tarball into the repository
                $ tar zxvf ../qt4-x11_4.5.2.orig.tar.gz --strip=1
      
                # Add all files to the index and commit the result
                $ git add -A
                $ git commit -m "Import upstream 4.5.2 release."
              
    2. Original source can be fetched from the remote upstream repository. For example, let's define a new remote 'qt' for original Qt sources.

                $ git remote add qt git://gitorious.org/qt/qt.git
                $ git remote update
                # Wait ...
                $ git branch upstream qt/master # optional
              
    Finally, read upstream tree to the packaging branch working tree, do:

           # (only once) Ignore everything (upstream source) but files under
           # debian/.
           $ git config core.excludesfile debian/upstreamignore
    
           # Make sure there are no dangling untracked files
           $ git clean -xdff
    
           # Checkout packaging branch
           $ git checkout master
    
           # Read upstream (can be any git commit'ish/tree'ish reference) sources
           # into the working tree
           $ git read-tree upstream
           $ git checkout-index -a
           $ git reset
    
           # Do packaging, committing, finally push...
         
  3. Do all packaging work in the private 'build' branch which is a merge of upstream (2a or 2b) and packaging branch. This scenario might be quite error prone and time consuming since packaging commits must be done in the packaging branch rather than build branch or later cherry-picked from the build to master branch.
    1. Committing to master directly:

             $ git checkout build # (or git checkout -b build upstream)
             $ git merge upstream # (or git reset --hard upstream)
             $ git merge master
      
             # Do work
             $ git checkout master
             $ git commit
             $ git checkout build
             $ git merge master
      
             # Do more work
             $ git checkout master
             $ git commit
             ...
           
    2. Cherry-picking (or rebasing) from build branch:

             $ git checkout build # (or git checkout -b build upstream)
             $ git merge upstream # (or git reset --hard upstream)
             $ git merge master
      
             # Do work
             $ git commit
             # Do more work
             $ git commit
             ...
             # Done. Now merge packaging changes back to master.
      
             # Either
             $ git checkout master
             $ git cherry-pick commit1
             $ git cherry-pick commit2
             ...
             $ git branch -D build # build branch becomes useless
      
             # OR convert build branch into master using rebase
             $ git rebase -i --onto master `git merge-base upstream master`
             $ git checkout master
             $ git reset --hard build
      
             # Tag, push etc.
            
Feel free to use whatever workflow you like most (or any other). In general, workflow #3 looks more cumbersome but it's nearer the proper Git way. However, workflows #1 are #2 are somewhat simpler even if lower level git commands are used. What is more, they give you less headache when managing patches with quilt because Git is told to ignore everything but debian/ subdirectory hence it won't track changes made by `quilt push`. This way you can always be sure that `git commit -a` won't pick up any raw patches to upstream source regardless if anything is quilt pushed or not.

[1] Available in the quilt package on Debian based systems. quilt must be invoked with QUILT_PATCHES environment variables set to debian/patches.
[2] Available in the git-core package on Debian based systems.