Developing LHCb Software

Structure of the LHCb code repositories

The LHCb code is organized in a number of projects with different roles. In order to provide functionality to the experiment, a number of those projects are compiled together in what we call a stack.

LHCb software is versioned using the GIT version control system, hosted by the GitLab server instance at CERN (https://gitlab.cern.ch), within the lhcb group, with one repository per project.

Each project repository contains a README.md and/or a CONTRIBUTING.md file with specific details about each projects and rules to contribute. Within each git repository, several branches of the code have been created in order to develop and maintain the code needed to process the data recorded by the LHCb experiment, they are listed in:

https://twiki.cern.ch/twiki/bin/viewauth/LHCb/SoftwareReleaseSchedules

by the Physics Application Coordination (PAC) meeting, which coordinates the releases of the LHCb software stack.

As a general rule, the master branch of the projects is for developments and is the place to commit new features, while the *-patches branches have a specific purpose.

For example, the 2024-patches branch in a project is dedicated to the code to process 2024 data and as such only contains the features considered necessary for this purpose by the LHCb RTA and DPA projects.

This is not the case for all repositories however: in the case of Detector, the changes should ALWAYS be applied to master first and later backported to 2024-patches. There is a risk of a clash between the component/LHCb version names in the compact folder otherwise. Of course, only changes affecting the 2024 version of the detector have to be ported back.

Therefore, when developing new features, it is necessary to get in touch with the project responsible(s) to see which branch the merge request should target, and whether the feature needs to be subsequently ported to other branches. The CONTRIBUTING.md file in a project will in any case document its specificities.

Development process

A number of general best practices should be followed when creating merge requests to the LHCb code base, as presented during the 110th LHCb Week.

Setting up the case for a development

New features should be motivated and discussed within the appropriate group.

This can be done in different ways depending on the software project, by creating a gitlab issue and/or present the problem in the related meeting. New merge requests not validated should be created with the DRAFT status.

In all cases the project coordination teams should be involved in the discussion in all cases to give feedback on development details, person-power and prioritisation of the work.

Feature development

The fun part of the job!

To organize the development it is better to:

  • always implement feature in a dedicated feature branch, avoiding to mix several developments in the same merge request.

  • if possible, split large developments in smaller independent features that can be merged one by one. This avoids having long lived feature branches that have to be rebased on a regular basis.

  • split the functionality implemented in a branch in a small number of meaningful commits. In git, it is possible to merge commits and simplify the history of a branch a posteriori. Failing this, the “squash commits” functionality of gitlab can be used, it groups all changes in a merge request in one commit (it effectively does git merge –squash)

  • always rebase the feature branch (instead of merging from the target). In any case, avoid mixing rebase and merge commits.

  • commit with messages meaningful to anybody reading the history of the code. They should be short but descriptive of the change done.

Do not forget to check the compiler output and that the tests necessary to validate the development are in place:

  • The code should compile without warnings and run on representative samples (for instance, if you are adding a fix for a vN decoding version, you should test with simulation data corresponding to that version)

  • If your code is covered by existing qmt or ci-tests you should run them locally.

  • If you expect your development to change results of existing tests, you should make this clear in your MR description (why and by how much).

  • If your development is not covered by existing tests, you should add new ones. This ensures that your new development is properly tested and that it will keep working with future developments.

Code review

Once you are done with development and local tests, the code does what you want it to do… But it does not end here!

  • Now your MR is ready to be reviewed (no need for DRAFT status)

  • You will need assign reviewers, i.e. colleague with experience in the topic, code owner or WP coordinators, who might assign someone else

  • If you don’t know who to assign, mark your MR as ready and ping the software shifter/WP coordinators, letting them know you’re searching for a reviewer. They will follow up and ensure someone with relevant experience is assigned to your MR.

  • The reviewer(s) will probably have comments for you, both on the performance and physics outcome of your development but also on technical details such as coding practices, maintainability, style etc. - please follow up with them in a kind and professional manner Our codebase is used by every LHCb analysis - code review is crucial!

Integration tests and merging

Once your MR has been reviewed, assign the software shifter (for RTA, or WP coordinators/application managers for DPA/simulation) for ci-testing.

  • This will ensure that your development works in all the necessary environments and configurations (for instance optimized vs debug builds).

  • Once the tests are done, the person responsible of the test will let you know if there are any problems related to your development - you can ping them if necessary.

  • You may also launch the ci-tests on your own if you know what you are doing (checking the available jenkins resources and handling dependencies) - but be aware that in that case you are responsible for checking the results of your test!

Once tests have run:

  • The software shifter/maintainer will check them (or you can check them yourself): they will make sure differences in refs are expected, and point out any failing test that might be due to your changes.

  • If you do not know why a test is failing, or you think it i s unrelated to your development, explain why. The shifter/maintainer should be able to help understanding this, but you need to point them in the right direction.

  • If there are unexpected changes or tests failing due to your MR, debug it and go back to the development step once done. Keep the reviewers in the loop so they can comment and help during the debugging process.

  • Do not update references by yourself!

Once all the tests are successful, the maintainer will be assigned for merging:

  • Please be patient as often many MRs are in the queue and they need to be scheduled. Keep an eye on the MR in case the maintainer spots any last minute issue and try to react promptly.

  • Be ready to rebase your code, as it might conflict with other developments.

Getting the code and compiling

Full stack

It is possible to compile a full stack using Rosen’s lb-stack-setup tool (https://gitlab.cern.ch/rmatev/lb-stack-setup).

Another tool was developed in the context of the Upgrade 1 hackathons (https://gitlab.cern.ch/lhcb/upgrade-hackathon-setup), still usable today.

Satellite project

Description

Working with satellite projects (AKA local projects) is very useful for quick (a few commits) or limited (a few packages) developments.

First we need to create the satellite project:

lb-dev Project/vXrY
cd ProjectDev_vXrY

then declare which project we want to get packages from:

git lb-use Project

and get the package/subdirectory code, from the master (or another) branch:

git lb-checkout Project/master Some/Package

or from a given project version:

git lb-checkout Project/vXrY Some/Package

At this point, we can work on the changes we need to make, for example:

vim Some/Package/src/MyStuff.cpp
make
make test
git add Some/Package/src/MyStuff.cpp
git commit -m 'fixing feature abc (JIRATICKET-123)'
vim Some/Package/src/MyStuff.cpp
make
make test
git commit -a -m 'improved fix to JIRATICKET-123'

Once we are happy with our changes, we can push them to a branch (JIRATICKET-123 in this example) in the remote repository for the project:

git lb-push Project JIRATICKET-123

and create a merge request, by going to the project page on https://gitlab.cern.ch/ and clicking on plus then “New merge request”. If you add [WIP] at the front of the merge request’s title, it is not merged automatically. This gives people the chance to review your changes and accept the merge request.

Mixing branches

In git, one does not just commit the current content of a file, but a change history. That means whenever you commit work, git needs to know which older version of a branch your change should be applied to. When checking out files from multiple branches with git lb-checkout, this will lead to confusion (i.e. error messages about merge conflicts when doing git lb-push). In this case a combination of vanilla git and git-lb commands might be useful.

Example: You want to commit changes on top of the 2018-patches branch of a project, but pick the master version of a few files for that. You want to use the nightly that was compiled last Monday. The steps then look like:

lb-dev --nightly=lhcb-2018-patches Mon DaVinci/2018-patches
cd ./DaVinciDev_2018-patches
git lb-use Phys
# checkout Phys/LoKiPhys with
git lb-checkout Phys/2018-patches Phys/LoKiPhys
# checkout three files from the master branch with vanilla git
git checkout Phys/master -- Phys/LoKiPhys/python/LoKiPhys/functions.py
git checkout Phys/master -- Phys/LoKiPhys/LoKi/BeamLineFunctions.h
git checkout Phys/master -- Phys/LoKiPhys/src/BeamLineFunctions.cpp
# edit Phys/LoKiPhys/python/LoKiPhys/functions.py to resolve small bug fix
git add Phys/LoKiPhys/python/LoKiPhys/functions.py
git commit
git lb-push Phys My_awesome_feature

The git lb-push command then should not fail in merge conflicts and is suited for a merge request into the 2018-patches branch (i.e. the branch used in the git lb-checkout command).

Single project

The tools to work with satellite projects have limitations. In particular they fail on binary files and do not support branch juggling.

For this reason and because working with plain git is better, it’s generally suggested to work on whole projects with a workflow like:

git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/lhcb/Project.git
cd Project
lb-project-init
# use '-b' only if that branch does not exist in the remote repository
git checkout -b JIRATICKET-123
make
make test
# edit edit edit...
git add Some/Package/src/MyStuff.cpp
git commit -m 'fixing feature abc (JIRATICKET-123)'
vim Some/Package/src/MyStuff.cpp
make
make test
git commit -a -m 'improved fix to JIRATICKET-123'
git push -u origin JIRATICKET-123

Data Packages

Since December, 12 2017 data packages are in managed in Gitlab (see announcement on lhcb-core-soft).

To work on a data package is equivalent, in some sense, to working with full projects.

You can get a local clone of a data package with something like git clone https://gitlab.cern.ch/lhcb-datapkg/Hat/Name.git Hat/Name, or, as a handy shortcut, git lb-clone-pkg Hat/Name. So, for example:

git lb-clone-pkg Gen/DecFiles
cd Gen/DecFiles
git checkout -b ${USER}/my-changes
# edit edit edit
git add dkfiles/YourDecFile.dec
git add doc/release.notes
git commit -m "Added dkfiles for XXX"
git push -u origin ${USER}/my-changes
# create merge request

If you have a full stack checked out, you can do the following:

#from your stack directory
mkdir DBASE
cd DBASE
git lb-clone-pkg PRConfig
cd ..
make Brunel/purge
make

The purge is annoying but necessary. Do not purge the whole stack, just the folder with the application (Brunel, Moore, DaVinci). Then you avoid a costly recompilation.

Examples

To better understand how to apply the recipes, here we have a few specific examples.

Upgrade Tracking

Use case: work on a few packages from different projects in a specific nightly build slot.

Note: The branch upgradeTracking was merged to master and deleted. Therefore, from now on it is recommended to use the master branch.

Development:

#Create environment
lb-dev --nightly lhcb-head Brunel/HEAD
#for a specific nightly add Mon,Tue,Wed,Thu,Fri,Sat,Sun as i.e.: lb-dev --nightly lhcb-head Mon Brunel/HEAD

cd BrunelDev_HEAD

# Add packages from Rec that you want to modify. e.g.:
git lb-use Rec
git lb-checkout Rec/master Tr/TrackFitter
git lb-checkout Rec/master Tf/TrackSys

#contains properties of the tracking sequence git
git lb-checkout Rec/master Pr/PrAlgorithms
#contains tracking algorithm ( Seeding/Forward/Matching/Downstream )
git lb-checkout Rec/master Pr/PrMCTools

#contains truth matching tool and tools to study detector properties
git lb-checkout Rec/master Pr/PrKernel
#contains base classes and interfaces used by PrAlgorightms and PrMCTools

# Add Brunel for testing: git lb-use Brunel git lb-checkout
Brunel/master Rec/Brunel

# add/change files

#Compile
make

#locally commit the code
git commit -a -m "changed something"

#Test the changes #run all qm tests make test #or, for specific tests:
make test ARGS="-R brunel-upgrade-baseline"

#push to server
git lb-push Rec upgrade-newbranchname

Merge requests

Update local packages after the merge requests are applied:

cd BrunelDev_master
git fetch --all
git lb-checkout Rec/master Tr/TrackFitter
git lb-checkout Brunel/master Rec/Brunel

Upgrade Tracking Example 2

Use case: work on significant changes to the tracking code, building packages from scratch

Preparation (can be setup as a shell script for easy rebuilds):

source /cvmfs/lhcb.cern.ch/lib/LbEnv-stable # Only needed for non-lxplus
systems #lb-set-platform ${CMTCONFIG/opt/dbg} # Uncomment for debug
builds export
CMAKE_PREFIX_PATH="$HOME/upgradeTracking:/cvmfs/lhcbdev.cern.ch/nightlies/lhcb-upgradeTracking/Today:${CMAKE_PREFIX_PATH}"
export CCACHE_DIR=/<somewhere>/.ccache export
CMAKEFLAGS=-DCMAKE_USE_CCACHE=ON unset VERBOSE

Note that for best performance you should pick /<somewhere> local to the machine you run on. Also, you should increase the cache size a bit, as the default is a little small. For instance the following will set the size to 10G:

ccache --max-size=10G

Building (using ssh for gitlab authentication):

mkdir ~/upgradeTracking

cd ~/upgradeTracking
git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/lhcb/LHCb.git LHCB/LHCB_upgradeTracking
cd LHCB/LHCB_upgradeTracking
git checkout -b upgradeTracking origin/upgradeTracking

cd ~/upgradeTracking
git clone --recurse-submodules    ssh://git@gitlab.cern.ch:7999/lhcb/Lbcom.git LBCOM/LBCOM_upgradeTracking
cd LBCOM/LBCOM_upgradeTracking
git checkout -b upgradeTracking origin/upgradeTracking

cd ~/upgradeTracking
git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/lhcb/Rec.git REC/REC_upgradeTracking
cd REC/REC_upgradeTracking
git checkout -b upgradeTracking origin/raaij-upgradeTracking

cd ~/upgradeTracking
git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/lhcb/Brunel.git BRUNEL/BRUNEL_upgradeTracking
cd BRUNEL/BRUNEL_upgradeTracking
git checkout -b upgradeTracking origin/upgradeTracking

Edit each of the CMake lists in the last three packages to use the upgradeTracking version instead of the versions listed for the above packages. In each directory, in order, run the following commands to build:

lb-project-init make configure make install

Note: if you want or need to use prerelease versions of heptools you can edit the toolchain.cmake file created by the lb-project-init command with the additional lines at the top:

set(CMAKE_PREFIX_PATH /cvmfs/lhcb.cern.ch/lib/lhcb /cvmfs/lhcb.cern.ch/lib/lcg/releases /cvmfs/sft.cern.ch/lcg/releases ${CMAKE_PREFIX_PATH})
list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH)

which adds the location of the central heptools location as used by the nightly builds.

Tips & Tricks

Remove from a local project a package checked out with “git lb-checkout”

If in your local project you have a copy of a package you do not need anymore, you can safely remove it from the local repository and remove the associated metadata with:

cd ~/cmtuser/MyProjectDev_vXrY
git rm -r Hat/MyPackage
git config -f .git-lb-checkout --remove-section lb-checkout.TheProject.Hat/MyPackage
git add .git-lb-checkout
git commit -m 'removed Hat/MyPackage'

where you replace TheProject and Hat/MyPackage with the correct values (you can use git config -l -f .git-lb-checkout to be sure).

Commit a change to both master and run2-patches branches

master and run2-patches branches are distinct branches for run3 and run1/run2 development respectively. Both branches are in the process of being cleaned up to contain only code relevant for the supported run period, but some of the code is shared. When making a fix or adding a new feature, think whether it is relevant to both branches - if so you should commit it to both. While it is always possible to make distinct commits to the two branches, it is usually cleaner to make the commit to one branch and then cherry-pick it to the other, as this gives a more legible Git history and can avoid merge conflicts in future. Just make the merge request to one of the two branches and make a note in the MR description for the release manager to port to the other branch. Depending on the type of change it may be better to start from one branch rather than the other: for bug fixes, it is usually better to apply first to run2-patches=; for new features, apply first to =master

N.B. if your branch originated from anything other than the target branch, you must first “rebase” the branch, see instructions below

Commit a change to a legacy xxx-patches branch

Legacy branches are intended for maintenance of software versions used in official processings (e.g. a Reco or Stripping version, but also the trigger for a given year). As such, their behaviour should not be modified, so any changes should be considered carefully: it is OK to add new features, but generally not OK to modify algorithms in ways that change their performance, even if it’s a bug fix. When propagating a new feature to a (set of) legacy branch(es), it is best to start from the most recent branch (generally, run2-patches) and back port. This is best done by a release manager, just make a note in the MR description of the MR that introduces the change, which legacy branches it should be back-ported to.

Rebase a feature branch to a different origin branch

Sometimes you may have been working on a new feature or bug fix in a branch that you created starting from e.g. master, but you wish to make the merge request against another branch, e.g. run2-patches. Before you push your branch you need to rebase it. In the following example, we assume that you are working on a feature branch called myFeatureBranch in Phys project and wish to rebase it to run2-patches branch. Proceeed as follows:

cd $TMPDIR
git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/lhcb/Phys.git
cd Phys
git checkout myFeatureBranch
git rebase -i origin/run2-patches
# an editor opens. You should keep only the lines with your commits and save
git log
# make sure the history looks right
git push --force # much better to use --force-with-lease, but you might not have it in your git version
# see e.g. https://developer.atlassian.com/blog/2015/04/force-with-lease/

Port an existing commit to another branch

Sometimes you wish to commit a change to more than one branch. If you cannot rely on the automatic merging described in previous headings, use the git cherry-pick command: once your commit(s) is in a given branch, just checkout the other branch and issue:

git cherry-pick sha1 [...]

where sha1 is the name of your commit, or a space separated list of commits (in the order they should be applied).

cherry-picking may trigger conflicts if the commit does not apply cleanly. In such a case, one has to resolve the conflicts, readd the fixed files to the index and say:

git cherry-pick --continue

as explained by git on its output

Last remark : if you find somewhere that you could achieve something similar using git merge –ours or –theirs, this is a very bad idea ! These commands are explicitly revoking commits, so losing work. they actually mean “Keep our/their work, and revoke their/our work”. This reverting will even be merged into other branch in the future.

Move packages between projects

Warning

Please use this recipe with care!

Note

An older recipe exists in this JIRA comment which has the disadvantage that it starts a new line of history with an unrelated root commit.

Prerequisites

This was tested with Git 2.26.2 and you need git-filter-repo 2.29.0 or later. Download an archive from https://github.com/newren/git-filter-repo/releases/, extract it with tar xf <filename> and the directory to PATH.

The goal is to move packages (directories) from one git repository to another, while preserving the full git history. This is done by filtering the commits in the source repository using git-filter-repo. Then, the new filtered history containing only the changes-to-be-moved is transplanted on top of the desired destination repository branch (e.g. master) using git rebase --rebase-merges --root.

As part of the filtering step, the commit messages are rewritten (see screenshot below) to

  1. append a link to the source commit message (e.g. Moore@123456789),

  2. replace short references to issues and MRs such as #12345 with Moore#12345.

Note that the sources are not modified in any way during the filtering. There might be tweaks necessary on top of the automatic move in order for the packages to work fine from within the destination project. Also, any short references to issues or MRs will not make sense unless one knows about the move.

Here is an example of how a moved commit looks like on GitLab:

_images/move-packages.png

Filter source repository

setopt nobanghist 2> /dev/null || set +H  # disalbe history expansion (zsh or bash)

SOURCE=Moore
FILTERS=(--path This/Package1 That/Package2)

git clone ssh://git@gitlab.cern.ch:7999/lhcb/$SOURCE.git
cd $SOURCE
git filter-repo "${FILTERS[@]}" --commit-callback "
import re
ORIGIN = '$SOURCE'
message = commit.message.decode()
message = re.sub(r'(\s)([#!][0-9]+)', r'\1{}\2'.format(ORIGIN), message)
message = message.rstrip('\n')
message += '\n\nMoved from {}@{}\n'.format(ORIGIN, commit.original_id.decode())
commit.message = message.encode()
" --dry-run
# Check the filtered and transformed commits
less .git/filter-repo/fast-export.filtered
# If happy, re-run without --dry-run
# ...
cd ..

Add commits to the destination repository

DESTINATION=LHCb
git clone ssh://git@gitlab.cern.ch:7999/lhcb/$DESTINATION.git
cd $DESTINATION
git remote add src ../$SOURCE
git fetch src
git rebase --rebase-merges --root src/master --onto origin/master

Dealing with conflicts

As the git manual for --rebase-merges points out, “Any resolved merge conflicts or manual amendments in these merge commits will have to be resolved/re-applied manually”.

Whenever you get into a conflicted state, check the conflict carefully with git diff. It can be very useful to use the diff3 conflict style (see here for some details):

git config --global merge.conflictstyle diff3

It is usually fine to automatically resolve the conflicts by taking the incomming change, which you can do with git checkout --theirs path/to/file.

Verify the final package contents and push

To check that the final package contents are identical in the source and the destination repository, you can do the following:

git diff src/master..HEAD -- This/Package1 That/Package2

If there are no differences, you can proceed to create a branch and push it:

git checkout -b move-packages-XYX
git push -u origin move-packages-XYZ

If necessary, follow up with tweaks of the package contents in new commits.

Add a package to a project

git clone --recurse-submodules https://:@gitlab.cern.ch:8443/lhcb/TheProject.git
cd TheProject
git checkout -b ${USER}/MyNewPackage
# copy the files
git add Hat/MyNewPackage
git commit -m 'add package Calibration/Pi0Calibration'
git push -u origin ${USER}/MyNewPackage

where you replace TheProject and Hat/MyNewPackage with the appropriate values

Formatting code for LHCb

As discussed at the 11th LHCb Computing Workshop and detailed in a Core Software Meeting, contributions to LHCb code have to be formatted according to common LHCb style. To avoid issues with different interpretations of the style, the rules are applied using the automatic tools clang-format (for C++) and YAPF (for Python). A helper command (lb-format) is available to simplify the interaction with the low level tools.

Formatting individual files

The simplest way to format a C++ or Python file is to call lb-format on them:

cd <Project>
lb-format MyPkg/src/MySource.cpp MyPkg/python/MyPkg/SomePython.py

lb-format ignores unsupported file types (printing a warning), so it’s safe to call it with something like:

cd <Project>
git ls-files | xargs -r lb-format find MyPkg -type f | xargs -r lb-format

Formatting only files modified wrt to a reference branch

When working on large projects, running a no-op formatting on all files takes a lot of time, so it’s useful to run it only on the files you are working on.

Assuming you are working on a branch that you want to merge into origin/master, you can do something like:

cd <Project>
lb-format --format-patch - origin/master | git am

for files already committed, or:

cd <Project> git diff --name-only --diff-filter=MA | xargs -r lb-format

for files not committed yet.

Troubleshooting

Merge conflict in gitlab

You have pushed your commits to gitlab into a branch, you try to merge with the master or some other branch, and gitlab tells you there is a merge conflict.

The currently easiest way to see where the merge conflict is:

git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/lhcb/<Project>.git
cd <Project>
git checkout <your branch>
git merge <target branch>
# <solve conflict> (Remove every >>>>> or <<<<<< )
git commit
git push origin <your branch>

Go back to gitlab and check if you can merge now.

Conflict after the global re-format of the project

This is a pretty rare case… I’ll fill the blank ASAP.

Warning about push.default not being set

When calling git push from a CentOS7 machine, you may get this warning:

| <verbatim> warning: push.default is unset; its implicit value is changing in Git 2.0 from ‘matching’ to ‘simple’. To squelch this message and maintain the current behavior after the default changes, use:

git config –global push.default matching

To squelch this message and adopt the new behavior now, use:

git config –global push.default simple

See ‘git help config’ and search for ‘push.default’ for further information. (the ‘simple’ mode was introduced in Git 1.7.11. Use the similar mode ‘current’ instead of ‘simple’ if you sometimes use older versions of Git) </verbatim> |

To fix it you need to call git config --global push.default xyz, as described in #Prerequisites.

Warning about not being able to push to the repository

There are three ways to access the git repostory, for example for the Rec package they are:

| Access | Git URL |

Kerberos

https://:@gitlab.cern.ch:8443/lhcb/Rec.git

HTTPS

https://gitlab.cern.ch/lhcb/Rec.git

ssh

ssh://git@gitlab.cern.ch:7999/lhcb/Rec.git

The trailing .git is not always necessary but push errors can occur due to the redirection from the url w/o .git to the complete one. Ensure the .git is present with git remote -v.

A remote repository url can in anyway be changed with:

git remote set-url Rec <new url>

The command git lb-use project sets the Kerberos method, so anyone with access to their CERN AFS area should be able to push changes to gitlab.cern.ch. If you are working outside CERN the ssh access may be a better option, you must first register your ssh key with CERN (see https://cern.service-now.com/service-portal/article.do?n=KB0003136 for details).

To either set or reset the remote site use the command:

git remote -v

to view the current remote repositories. Then:

git remote set-url Rec ssh://git@gitlab.cern.ch:7999/lhcb/Rec.git

to adjust a repository or:

git remote add -f Brunel ssh://git@gitlab.cern.ch:7999/lhcb/Brunel.git

to add a new repository. The official repository links can be found on the gitlab.cern.ch home page for each package.

You can globally switch between ssh and Kerberos authentication with the following entry in your ~/.gitconfig file:

[url "ssh://git@gitlab.cern.ch:7999"]
   insteadOf = https://:@gitlab.cern.ch:8443

a downside is that with Kerberos, for public repositories, authentication is skipped for pull actions. With ssh one needs to unlock the ssh keyring for pushing and pulling. An alternative is to finetune:

[url "ssh://git@gitlab.cern.ch:7999"]
   pushInsteadOf = https://:@gitlab.cern.ch:8443

which globally replaces all gitlab.cern.ch access from Kerberos to ssh for all push actions but leaves pull actions unchanged.

Dealing with submodules when changing branches (incl. checkout, pull, merge, cherry-pick)

We are using git submodules. The above git clone --recurse-submodules mostly takes care of that, except for changing branches with git checkout <branch> for branches that use different versions of a submodule. In this case, updating the submodule manually can be done with:

git submodule update --recursive

git submodule update --recursive can also be run when a project was cloned without the --recurse-submodules option.

Known Issues

  • git lb-push does not handle correctly binary files

  • after a git lb-push Project my-branch you have to call git lb-checkout Project/my-branch My/Package to continue working on the same branch