<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jwrm2</id>
	<title>Docswiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jwrm2"/>
	<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php/Special:Contributions/Jwrm2"/>
	<updated>2026-04-13T08:08:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1820</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1820"/>
		<updated>2025-07-30T10:15:49Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Checking out an older version of the master branch */ Formatted checkout command as code.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/softwarewales software]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
If the external potential already exists in some other repository and you will not need to make any changes to it at all, you can add the external repository directly rather than copying and using up space on our Gitlab. LAMMPS was added in this way, with a command like&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add https://github.com/lammps/lammps.git&lt;br /&gt;
&lt;br /&gt;
This approach is only likely to work for public repositories that do not need any kind of password to clone.&lt;br /&gt;
&lt;br /&gt;
There are a couple of useful options to be aware of. Commands like the above will create a new directory with the name of the repository. You can use a custom name by adding it after the repository URL. The command will use the default branch of the repository (usually &#039;master&#039; or &#039;main&#039;), but you can specify a different branch with the -b flag. For example&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add -b metatomic https://github.com/metatensor/lammps.git lammps_petmad&lt;br /&gt;
&lt;br /&gt;
will clone the metatomic branch of the lammps repository from metatensor, but put it in the directory lammps_petmad.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Checking out an older version of the master branch==&lt;br /&gt;
&lt;br /&gt;
There are all sorts of useful git tools for checking how individual files and branches have changed.&lt;br /&gt;
See the documentation for git diff for example. To check out the master branch current at a given date you can use:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout `git rev-list -1 --before=&amp;quot;Feb 11 2024&amp;quot; master`&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Each paper is a separate repository. To start a new paper, go to Gitlab and create a new repository by clicking the blue &#039;New Project&#039; button on your home screen. Create a blank project and make sure the project URL indicates it is under ch/wales rather than in your user space. Checkout the new repository and start writing the paper in the blank directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf documents either (except perhaps for proofs created by the journal). When it comes to revisions and resubmissions, do not create a new subdirectory for the new version. Git keeps the whole history so it is always possible to revert to a previous version.&lt;br /&gt;
&lt;br /&gt;
You will also want to checkout the [https://gitlab.developers.cam.ac.uk/ch/wales/bib bibliography repository] but you only need one copy of this, not one for each paper. A suitable directory structure might be to have a papers/ directory under your home directory that contains a directory for the bibliography repository and a directory for each paper you are currently working on.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1819</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1819"/>
		<updated>2025-07-30T10:15:15Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Creating a new submodule */ More details about adding a new submodule.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/softwarewales software]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
If the external potential already exists in some other repository and you will not need to make any changes to it at all, you can add the external repository directly rather than copying and using up space on our Gitlab. LAMMPS was added in this way, with a command like&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add https://github.com/lammps/lammps.git&lt;br /&gt;
&lt;br /&gt;
This approach is only likely to work for public repositories that do not need any kind of password to clone.&lt;br /&gt;
&lt;br /&gt;
There are a couple of useful options to be aware of. Commands like the above will create a new directory with the name of the repository. You can use a custom name by adding it after the repository URL. The command will use the default branch of the repository (usually &#039;master&#039; or &#039;main&#039;), but you can specify a different branch with the -b flag. For example&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add -b metatomic https://github.com/metatensor/lammps.git lammps_petmad&lt;br /&gt;
&lt;br /&gt;
will clone the metatomic branch of the lammps repository from metatensor, but put it in the directory lammps_petmad.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Checking out an older version of the master branch==&lt;br /&gt;
&lt;br /&gt;
There are all sorts of useful git tools for checking how individual files and branches have changed.&lt;br /&gt;
See the documentation for git diff for example. To check out the master branch current at a given date you can use:&lt;br /&gt;
&lt;br /&gt;
git checkout `git rev-list -1 --before=&amp;quot;Feb 11 2024&amp;quot; master`&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Each paper is a separate repository. To start a new paper, go to Gitlab and create a new repository by clicking the blue &#039;New Project&#039; button on your home screen. Create a blank project and make sure the project URL indicates it is under ch/wales rather than in your user space. Checkout the new repository and start writing the paper in the blank directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf documents either (except perhaps for proofs created by the journal). When it comes to revisions and resubmissions, do not create a new subdirectory for the new version. Git keeps the whole history so it is always possible to revert to a previous version.&lt;br /&gt;
&lt;br /&gt;
You will also want to checkout the [https://gitlab.developers.cam.ac.uk/ch/wales/bib bibliography repository] but you only need one copy of this, not one for each paper. A suitable directory structure might be to have a papers/ directory under your home directory that contains a directory for the bibliography repository and a directory for each paper you are currently working on.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1813</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1813"/>
		<updated>2023-08-08T09:33:06Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Writing a Paper */ Fixed bib repository link.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/softwarewales software]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Each paper is a separate repository. To start a new paper, go to Gitlab and create a new repository by clicking the blue &#039;New Project&#039; button on your home screen. Create a blank project and make sure the project URL indicates it is under ch/wales rather than in your user space. Checkout the new repository and start writing the paper in the blank directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf documents either (except perhaps for proofs created by the journal). When it comes to revisions and resubmissions, do not create a new subdirectory for the new version. Git keeps the whole history so it is always possible to revert to a previous version.&lt;br /&gt;
&lt;br /&gt;
You will also want to checkout the [https://gitlab.developers.cam.ac.uk/ch/wales/bib bibliography repository] but you only need one copy of this, not one for each paper. A suitable directory structure might be to have a papers/ directory under your home directory that contains a directory for the bibliography repository and a directory for each paper you are currently working on.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1812</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1812"/>
		<updated>2023-08-08T09:31:55Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Writing a Paper */ Updated to reflect having a repository per paper.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/softwarewales software]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Each paper is a separate repository. To start a new paper, go to Gitlab and create a new repository by clicking the blue &#039;New Project&#039; button on your home screen. Create a blank project and make sure the project URL indicates it is under ch/wales rather than in your user space. Checkout the new repository and start writing the paper in the blank directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf documents either (except perhaps for proofs created by the journal). When it comes to revisions and resubmissions, do not create a new subdirectory for the new version. Git keeps the whole history so it is always possible to revert to a previous version.&lt;br /&gt;
&lt;br /&gt;
You will also want to checkout the [git@gitlab.developers.cam.ac.uk:ch/wales/bib.git bibliography repository] but you only need one copy of this, not one for each paper. A suitable directory structure might be to have a papers/ directory under your home directory that contains a directory for the bibliography repository and a directory for each paper you are currently working on.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1811</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1811"/>
		<updated>2023-08-08T09:22:06Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Initial Checkout */ Updated Gitlab link.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/softwarewales software]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1810</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1810"/>
		<updated>2023-08-08T09:21:18Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Initial Checkout */ Changed from papers to software.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/softwarewales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1809</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1809"/>
		<updated>2023-08-08T09:19:47Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Working on the group code */ Instructed to compile with nagfor before merging.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You should assign the request to yourself and anyone else who has worked on this branch. Choose the person who is going to review for you. Make sure you tick the boxes to delete the feature branch after the request is accepted. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you select as reviewer will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. However, the reviewer will not be doing extensive testing, so it remains your responsibility to follow the coding standards and make sure everything works. You should make sure your changes compile with nagfor before submitting the merge request, as that is the most particular compiler. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1808</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1808"/>
		<updated>2023-01-26T16:30:32Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Submodules */ Typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the repository and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finished with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turning an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1807</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1807"/>
		<updated>2022-12-19T13:43:28Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Creating a new submodule */ Typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the reporistory and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directpory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finihsed with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turing an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered an advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1806</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1806"/>
		<updated>2022-12-19T13:43:03Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Added submodule information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Submodules==&lt;br /&gt;
&lt;br /&gt;
Our software repository has become quite large as external potentials have been added. Submodules offer a way to compartmentalise the reporistory and speed up clones and updates. Self-contained third-party potentials are good candidates for splitting off into submodules. We will use GDML (Gradient-Descent Machine Learning) as an example. On an initial checkout, you will see a GDML/ directory in the root of the repository, but the directpory will be empty. Most users do not need GDML, so will not care or even be particularly aware that GDML has not be cloned.&lt;br /&gt;
&lt;br /&gt;
Let us suppose that you actually need GDML. You can tell git that it is required by running&lt;br /&gt;
&lt;br /&gt;
  $ git submodule init GDML&lt;br /&gt;
&lt;br /&gt;
Then the next time you run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update&lt;br /&gt;
&lt;br /&gt;
the contents of GDML will be checked out. If GDML is subsequently updated, run the update command again to get the newest version. If at some later point you decide that you have finihsed with GDML and no longer need it checked out, run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule deinit GDML&lt;br /&gt;
&lt;br /&gt;
and the GDML directory will be emptied. If the submodule you are interested in has its own submodules, add the --recursive flag to the commands. If you decide that you want all the submodules run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule update --init --recursive&lt;br /&gt;
&lt;br /&gt;
and all submodules will be checked out. This command is not recommended and you must have a good reason why you need all the submodules before you consider running it.&lt;br /&gt;
&lt;br /&gt;
===Creating a new submodule===&lt;br /&gt;
&lt;br /&gt;
If you are creating an interface to a new large external potential, it may be appropriate to add the external potential as a submodule. It is appropriate if the potential is quite large (more than a few MB), is being placed in the root of the repository, and is not likely to require much in the way of changes after the interface is set up. Instead of adding the external potential to the softwarewales repository, create a new repository under Wales Group on Gitlab and place the files there. Within softwarewales run&lt;br /&gt;
&lt;br /&gt;
  $ git submodule add git@gitlab.developers.cam.ac.uk:ch/wales/my_new_repository.git&lt;br /&gt;
&lt;br /&gt;
where my_new_repository is replaced with whatever you named the new repository. You could also got the appropriate URL by going onto Gitlab for the new repository, clicking the &#039;Clone&#039; button and copying. This command makes the necessary changes to the .gitmodules file, which will then need to be committed and pushed.&lt;br /&gt;
&lt;br /&gt;
Turing an existing subdirectory into a submodule is also possible, but is slightly more complicated and is considered and advanced topic. Google is your friend. Do not mess with the Gitlab repository until you are satisfied you have made the correct adjustments locally.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1796</id>
		<title>Compiling Wales Group codes using cmake</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1796"/>
		<updated>2022-09-09T14:04:06Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Extra command line build examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cmake.org/ CMake] (Cross-platform Make) provides a simple, platform independent way for us to compile and test the group codebase. Dependencies are handled automatically, compilation can proceed in parallel to avoid long waits while testing changes and builds are done entirely outside of the source directory. It also enables us to use the [[Jenkins CI]] &#039;build bot&#039; system to automatically compile and test the code on a nightly basis - helping us catch troublesome commits before they affect other users. &lt;br /&gt;
&lt;br /&gt;
Although everything below refers to compiling [[GMIN]] with the Intel &#039;&#039;ifort&#039;&#039; compiler and AMBER9 - the exact same procedure works for [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
&lt;br /&gt;
Note that not every option for our codes is expected to actually compile with every compiler, for example, anything using CHARMM35/36 will not compile with &#039;&#039;nagfor&#039;&#039; or &#039;&#039;gfortran&#039;&#039;. This is nothing to do with our code - it&#039;s a CHARMM issue. You can get an idea for what should work by looking at the automated [[Jenkins CI]] builds.&lt;br /&gt;
&lt;br /&gt;
==Preparing to compile==&lt;br /&gt;
Before you get started, you need to ensure that the machine you are planning to compile on has cmake 2.8 or higher installed. You can check the current version like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake --version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The clusters have a module for cmake 3.0, which you can load using the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.0.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You also need to create a directory to build the code in. We suggest that you create a directory for the compiler you are using within the program directory, under a subdirectory called &#039;builds&#039; - for example for compiling GMIN with ifort, you would make a directory here:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
cd ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can call these directories whatever you like - but make sure it is clear to you what they contain! You might also want to check which version of the compiler you have loaded. This is important as the different clusters and workstations may have different default versions loaded, some of which might not work properly. You can check the compiler version currently loaded using the same &#039;--version&#039; flag we used for &#039;&#039;cmake&#039;&#039; above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ifort --version&lt;br /&gt;
ifort (IFORT) 12.1.3 20120212&lt;br /&gt;
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To load a different compiler, you can use the &#039;&#039;module load&#039;&#039; or &#039;&#039;module swap&#039;&#039; commands. A list of all available modules can be accessed using:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module av&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are having problems compiling, one of the first things to check is whether it works with a different version of the compiler!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: When compiling GMIN, if you are getting the error that there is no implicit type for ERFC in ewald.f90, try using a newer version of your compiler. This should be the built-in complementary error function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling using the ccmake GUI interface to set options==&lt;br /&gt;
[[Image:Ccmake.png|thumb|ccmake set up to compile A9GMIN|200px|right]]&lt;br /&gt;
&lt;br /&gt;
One advantage using cmake has over make is that we can use the simple ccmake GUI. This interface lets us set options like compiling with AMBER9, or CHARMM35, toggle between &#039;Release&#039; and &#039;Debug&#039; builds (see below) - and examine and alter the flags being uses for the compilation if we wish. Before we can run ccmake, we need to specify the compiler and run cmake in our build directory (e.g. softwarewales/GMIN/builds/ifort). We specify the &#039;&#039;&#039;F&#039;&#039;&#039;ortran &#039;&#039;&#039;C&#039;&#039;&#039;ompiler by setting the &#039;&#039;&#039;$FC&#039;&#039;&#039; environment variable (in this case the Intel Fortran compiler, ifort), and then run &#039;&#039;cmake&#039;&#039; (on the command line), passing it the relative location of the [[GMIN]] source directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake ../../source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you run &#039;&#039;ls&#039;&#039;, you will see some cmake files have been generated:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  modules&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now run &#039;&#039;ccmake&#039;&#039; to open the GUI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ccmake .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To navigate between options, use the arrow keys. Options can be toggled by pressing Return. To compile [[GMIN]] with AMBER9 (A9GMIN), we need to toggle the &#039;&#039;WITH_AMBER&#039;&#039; option &#039;&#039;ON&#039;&#039;. Once you have done this, you need to configure and generate appropriate cmake info. This is done by pressing &#039;c&#039; to configure, &#039;e&#039; to exit and then &#039;g&#039; to generate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: for some builds (CHARMM with DFTB and CUDAGMIN), you might need to configure, exit and generate twice to set all necessary options&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now compile A9GMIN in parallel as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;-j8&#039; flag here tells make to use up to 8 &#039;threads&#039; when building. For optimal performance, you should keep this slightly greater than the number of cores (CPUs) the node you are working on has. If all goes well, you should now have an A9GMIN binary in your build directory - congratulations! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linking Fortran executable A9GMIN&lt;br /&gt;
[100%] Built target A9GMIN&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------------------- 15:23:45&lt;br /&gt;
&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
A9GMIN          cmake_install.cmake   libcudadummylib.a  libmylapack.a  NAB&lt;br /&gt;
AMBER           display_version.f90   libdummylib.a      Makefile       nab_binaries_built&lt;br /&gt;
CMakeCache.txt  GMIN                  libgminlib.a       modules        porfuncs.f90&lt;br /&gt;
CMakeFiles      libamber12dummylib.a  libmyblas.a        n&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Plain [[GMIN]] is also built at the same time should you need it. You can move this into your ~/bin directory if you like, or anywhere else in your &#039;&#039;$PATH&#039;&#039; to make running it simple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: If you want to use OPTIM with the new C++ implementation of the NEB routine, you will need to obtain the source code for that separately. See [https://wikis.ch.cam.ac.uk/wales/wiki/index.php/OPTIM here] for instructions.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling by setting options on the command line==&lt;br /&gt;
If you know the options you&#039;d like to set already (you can see them all in ccmake), you can save some time by passing them directly to &#039;&#039;cmake&#039;&#039; on the command line, bypassing the need for &#039;&#039;ccmake&#039;&#039;. For example, to compile A9GMIN (GMIN with the AMBER9 interface) using the Intel ifort compiler, you would run the following commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &#039;../../source&#039; is the relative location of the GMIN source directory. You can find some more examples of compiling from the command line below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: Sometimes you may get error&#039;&#039;&#039; (for example, Fatal Error: Can&#039;t open module file &#039;someModule.mod&#039; for reading at (1): No such file or directory) when following this procedure. In that case there are three things you could try: make sure you are building in a new directory, if that does not help run `make VERBOSE=1` instead of `make -j8` or simply switch to using ccmake.&lt;br /&gt;
&lt;br /&gt;
==Compiling with MPI==&lt;br /&gt;
To compile with MPI support add the following flags when running cmake on the command line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=mpif90 CC=mpicc cmake ../source -DCOMPILER_SWITCH=pgi -DWITH_MPI=yes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here -DCOMPILER_SWITCH=pgi assumes you&#039;re using the Portland &#039;&#039;pgi&#039;&#039; compiler. Make sure you have the correct modules loaded (in this case &#039;&#039;pgi&#039;&#039; and &#039;&#039;mpi-pgi&#039;&#039;), and that the particular mpi you want (in this case &#039;&#039;mpi-pgi&#039;&#039;) is listed before any other mpi&#039;s loaded (so that it has the highest priority). The modules can be loaded by typing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load pgi/64/&lt;br /&gt;
module load mpi/openmpi/pgi/64/1.6.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and you can check which modules are loaded and in which order/priority by the &#039;&#039;module list&#039;&#039; command. You may need to &#039;&#039;module unload &amp;lt;name&amp;gt;&#039;&#039; any other mpi&#039;s that are higher up in the list than the one you want. You can of course set the COMPILER_SWITCH and WITH_MPI flags in &#039;&#039;ccmake&#039;&#039; if you prefer.&lt;br /&gt;
&lt;br /&gt;
Note: It has been observed that pgi/64/15.1 leads to compilation errors, and for now, it is best to use pgi/64/14.9&lt;br /&gt;
&lt;br /&gt;
==Advanced mode - changing compiler flags with ccmake==&lt;br /&gt;
[[Image:Ccmakeadvanced.png|thumb|ccmake advanced mode|200px|right]]&lt;br /&gt;
&lt;br /&gt;
Although initially the &#039;&#039;ccmake&#039;&#039; GUI looks very simple, there is a lot going on under the hood. By pressing &#039;t&#039; you can enter &#039;Advanced mode&#039; which will show you all of the hidden options, for example the compiler flags that are being passed to &#039;&#039;make&#039;&#039; when you compile the code. You can also make changes to the flags here, for example if you would like to add &#039;-p&#039; to do  profiling. &lt;br /&gt;
&lt;br /&gt;
As with changing the build type, you simply select the field you&#039;d like to change using the arrow keys, press Return, make your changes and press Return again to save them. When you subsequently configure and generate as above, those altered flag will be used for the subsequent compilation.&lt;br /&gt;
&lt;br /&gt;
Note that these changes only apply in the build directory in which you make them.&lt;br /&gt;
&lt;br /&gt;
==Debugging runtime problems using gdb or valgrind==&lt;br /&gt;
If you are getting a segmentation fault, crash or other unexpected behaviour, you might want to run your job through a debugger like [http://www.gnu.org/software/gdb/ gdb] or [http://valgrind.org/ valgrind]. In order to maximise your chances of getting useful output, you should build a &#039;Debug&#039; version of the program you are having trouble. To do this, you can either change the &#039;&#039;CMAKE_BUILD_TYPE&#039;&#039; in &#039;&#039;ccmake&#039;&#039; to &#039;Debug&#039; (press Return, change &#039;Release&#039; to &#039;Debug&#039; and press Return again), or on the command line like so for GMIN with AMBER 9 using the Intel ifort compiler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then run the binary &#039;&#039;through&#039;&#039; gdb or valgrind as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
valgrind A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I won&#039;t cover debugging with these tools here as it&#039;s a science in itself! Do some Googling and ask for help as needed :)&lt;br /&gt;
&lt;br /&gt;
==Debugging compilation problems==&lt;br /&gt;
There are many ways to try and track down why your code is not compiling. Before you start changing compilers, building a &#039;Debug&#039; version or changing machines, you might want to try running make again with the &#039;&#039;VERBOSE&#039;&#039; option enabled. This will dump a lot of potentially useful output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VERBOSE=1 make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One possible gotcha: all .f and .f90 files in the relevant source directories will be compiled and added to a library. This is quite different from the old Makefile way of doing things, where source files were explicitly specified for compilation (via their corresponding .o file). So, if you are testing something by for instance copying code.f90 to code.myhack.f90 and code.orig.f90, then slightly editing a line or two of code.myhack.f90 and copying it back to code.f90 for use, this will probably cause linking problems due to multiply-defined subroutines (from all three files). The solution, if you must have alternative versions of the same file hanging round, is to differentiate the filenames by a suffix AFTER the .f[90] .&lt;br /&gt;
 &lt;br /&gt;
Another occasional issue is the unexplained compiler bug - a problem with the version of the compiler you happen to be using. You can can an idea for which compiler versions we expect to work by checking the Jenkins build-bot output, as described in the &#039;Seeing console output&#039; section of the [[Jenkins CI]] page. If you are using a different version of the compiler in question, consider swapping to the version Jenkins is using with &#039;module swap&#039;.&lt;br /&gt;
&lt;br /&gt;
If the error message you are getting doesn&#039;t make sense to you after some Googling, go and ask someone - we all have these problems. Things you can try first include trying a different compiler version, or an entirely different compiler e.g. pgi rather than ifort for example. You should bear in mind that as mentioned above, not all versions of each code will compile with every compiler. Make sure you&#039;re not trying to build something that isn&#039;t expected to work.&lt;br /&gt;
&lt;br /&gt;
==Extra command line build examples==&lt;br /&gt;
The below commands are absolutely not an exhaustive list, but should give you an idea of what is possible. You can use &#039;&#039;ccmake&#039;&#039; as described above to discover which variables (e.g. WITH_AMBER) can be manipulated on the command line like this. All of these examples assume your git repository is set up in &#039;&#039;/home/CRSID/softwarewales&#039;&#039; - make the appropriate modifications if you have it elsewhere.&lt;br /&gt;
&lt;br /&gt;
===GMIN===&lt;br /&gt;
&#039;&#039;&#039;A12GMIN&#039;&#039;&#039; (GMIN with AMBER12) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_amber12&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER12=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35GMIN&#039;&#039;&#039; (GMIN with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAGMIN&#039;&#039;&#039; (GMIN leveraging GPU minimisation via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_cuda&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBGMIN&#039;&#039;&#039; (GMIN with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===OPTIM===&lt;br /&gt;
&#039;&#039;&#039;A9OPTIM&#039;&#039;&#039; (OPTIM with AMBER9) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_amber&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER9=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35OPTIM&#039;&#039;&#039; (OPTIM with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAOPTIM&#039;&#039;&#039; (OPTIM leveraging GPU via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_cuda5.5&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN and OPTIM with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBOPTIM&#039;&#039;&#039; (OPTIM with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===PATHSAMPLE===&lt;br /&gt;
There are very few options for [[PATHSAMPLE]] as we don&#039;t need to worry about interfacing with a particular potential. As a result, every binary is simply called &#039;&#039;PATHSAMPLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Using nagfor (the NAG fortran compiler - check you have the module loaded - very strict!):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/nagfor&lt;br /&gt;
cd !$&lt;br /&gt;
FC=nagfor cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pgi (much more generous with coding slips/non-standard uses):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/pgi&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring defaults - for developers==&lt;br /&gt;
&lt;br /&gt;
Fortran compilers and their corresponding default settings are all controlled by the file $SVN/CMakeModules/FindFORTRANCOMPILER.cmake ($SVN is your svn root directory). In particular, we may wish to edit the flags used for each set of compilers and build type. These are contained in the following block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
   message(&amp;quot;Setting initial values for compiler flags&amp;quot;)&lt;br /&gt;
   if(COMPILER_SWITCH MATCHES &amp;quot;pgi&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-Mextend&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3 -Munroll -Mnoframe&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Mdwarf3 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-Mfree&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;gfortran&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-ffixed-line-length-200 -ffree-line-length-0&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
#      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fimplicit-none -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;${CMAKE_Fortran_FLAGS_DEBUG} -fimplicit-none&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-ffree-form&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;nag&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -kind=byte -maxcontin=3000&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-mismatch_all -O4&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-C=all -mtrace=all -gline -g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING) # js850&amp;gt; is this ever used?&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;ifort&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -heap-arrays -assume byterecl&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
# Warnings about temporary argument creation and edit descriptor widths are disabled with the final flags.&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-C -g -traceback -debug full -check all,noarg_temp_created -diag-disable 8290,8291&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-debug all -check all -implicitnone -warn unused -fp-stack-check -ftrapuv -check pointers -check bounds&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   else()&lt;br /&gt;
      message(FATAL_ERROR &amp;quot;unknown comiler switch: ${COMPILER_SWITCH}&amp;quot;)&lt;br /&gt;
   endif()&lt;br /&gt;
    SET(COMPILER_FLAGS_WERE_SET yes CACHE TYPE INTERNAL)&lt;br /&gt;
endif(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main if/elseif blocks correspond to compiler switches. Inside these, there are the default flags for each of our build types (release, debug and debug_slow), which are configured using ccmake. These can be edited, if we wish to change the default behaviour (e.g. a recent addition of -check all,noarg_temp_created -diag-disable 8290,8291 to disable annoying warning messages for ifort).&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1795</id>
		<title>Compiling Wales Group codes using cmake</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1795"/>
		<updated>2022-09-09T14:03:43Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Extra command line build examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cmake.org/ CMake] (Cross-platform Make) provides a simple, platform independent way for us to compile and test the group codebase. Dependencies are handled automatically, compilation can proceed in parallel to avoid long waits while testing changes and builds are done entirely outside of the source directory. It also enables us to use the [[Jenkins CI]] &#039;build bot&#039; system to automatically compile and test the code on a nightly basis - helping us catch troublesome commits before they affect other users. &lt;br /&gt;
&lt;br /&gt;
Although everything below refers to compiling [[GMIN]] with the Intel &#039;&#039;ifort&#039;&#039; compiler and AMBER9 - the exact same procedure works for [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
&lt;br /&gt;
Note that not every option for our codes is expected to actually compile with every compiler, for example, anything using CHARMM35/36 will not compile with &#039;&#039;nagfor&#039;&#039; or &#039;&#039;gfortran&#039;&#039;. This is nothing to do with our code - it&#039;s a CHARMM issue. You can get an idea for what should work by looking at the automated [[Jenkins CI]] builds.&lt;br /&gt;
&lt;br /&gt;
==Preparing to compile==&lt;br /&gt;
Before you get started, you need to ensure that the machine you are planning to compile on has cmake 2.8 or higher installed. You can check the current version like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake --version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The clusters have a module for cmake 3.0, which you can load using the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.0.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You also need to create a directory to build the code in. We suggest that you create a directory for the compiler you are using within the program directory, under a subdirectory called &#039;builds&#039; - for example for compiling GMIN with ifort, you would make a directory here:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
cd ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can call these directories whatever you like - but make sure it is clear to you what they contain! You might also want to check which version of the compiler you have loaded. This is important as the different clusters and workstations may have different default versions loaded, some of which might not work properly. You can check the compiler version currently loaded using the same &#039;--version&#039; flag we used for &#039;&#039;cmake&#039;&#039; above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ifort --version&lt;br /&gt;
ifort (IFORT) 12.1.3 20120212&lt;br /&gt;
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To load a different compiler, you can use the &#039;&#039;module load&#039;&#039; or &#039;&#039;module swap&#039;&#039; commands. A list of all available modules can be accessed using:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module av&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are having problems compiling, one of the first things to check is whether it works with a different version of the compiler!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: When compiling GMIN, if you are getting the error that there is no implicit type for ERFC in ewald.f90, try using a newer version of your compiler. This should be the built-in complementary error function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling using the ccmake GUI interface to set options==&lt;br /&gt;
[[Image:Ccmake.png|thumb|ccmake set up to compile A9GMIN|200px|right]]&lt;br /&gt;
&lt;br /&gt;
One advantage using cmake has over make is that we can use the simple ccmake GUI. This interface lets us set options like compiling with AMBER9, or CHARMM35, toggle between &#039;Release&#039; and &#039;Debug&#039; builds (see below) - and examine and alter the flags being uses for the compilation if we wish. Before we can run ccmake, we need to specify the compiler and run cmake in our build directory (e.g. softwarewales/GMIN/builds/ifort). We specify the &#039;&#039;&#039;F&#039;&#039;&#039;ortran &#039;&#039;&#039;C&#039;&#039;&#039;ompiler by setting the &#039;&#039;&#039;$FC&#039;&#039;&#039; environment variable (in this case the Intel Fortran compiler, ifort), and then run &#039;&#039;cmake&#039;&#039; (on the command line), passing it the relative location of the [[GMIN]] source directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake ../../source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you run &#039;&#039;ls&#039;&#039;, you will see some cmake files have been generated:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  modules&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now run &#039;&#039;ccmake&#039;&#039; to open the GUI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ccmake .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To navigate between options, use the arrow keys. Options can be toggled by pressing Return. To compile [[GMIN]] with AMBER9 (A9GMIN), we need to toggle the &#039;&#039;WITH_AMBER&#039;&#039; option &#039;&#039;ON&#039;&#039;. Once you have done this, you need to configure and generate appropriate cmake info. This is done by pressing &#039;c&#039; to configure, &#039;e&#039; to exit and then &#039;g&#039; to generate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: for some builds (CHARMM with DFTB and CUDAGMIN), you might need to configure, exit and generate twice to set all necessary options&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now compile A9GMIN in parallel as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;-j8&#039; flag here tells make to use up to 8 &#039;threads&#039; when building. For optimal performance, you should keep this slightly greater than the number of cores (CPUs) the node you are working on has. If all goes well, you should now have an A9GMIN binary in your build directory - congratulations! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linking Fortran executable A9GMIN&lt;br /&gt;
[100%] Built target A9GMIN&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------------------- 15:23:45&lt;br /&gt;
&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
A9GMIN          cmake_install.cmake   libcudadummylib.a  libmylapack.a  NAB&lt;br /&gt;
AMBER           display_version.f90   libdummylib.a      Makefile       nab_binaries_built&lt;br /&gt;
CMakeCache.txt  GMIN                  libgminlib.a       modules        porfuncs.f90&lt;br /&gt;
CMakeFiles      libamber12dummylib.a  libmyblas.a        n&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Plain [[GMIN]] is also built at the same time should you need it. You can move this into your ~/bin directory if you like, or anywhere else in your &#039;&#039;$PATH&#039;&#039; to make running it simple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: If you want to use OPTIM with the new C++ implementation of the NEB routine, you will need to obtain the source code for that separately. See [https://wikis.ch.cam.ac.uk/wales/wiki/index.php/OPTIM here] for instructions.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling by setting options on the command line==&lt;br /&gt;
If you know the options you&#039;d like to set already (you can see them all in ccmake), you can save some time by passing them directly to &#039;&#039;cmake&#039;&#039; on the command line, bypassing the need for &#039;&#039;ccmake&#039;&#039;. For example, to compile A9GMIN (GMIN with the AMBER9 interface) using the Intel ifort compiler, you would run the following commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &#039;../../source&#039; is the relative location of the GMIN source directory. You can find some more examples of compiling from the command line below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: Sometimes you may get error&#039;&#039;&#039; (for example, Fatal Error: Can&#039;t open module file &#039;someModule.mod&#039; for reading at (1): No such file or directory) when following this procedure. In that case there are three things you could try: make sure you are building in a new directory, if that does not help run `make VERBOSE=1` instead of `make -j8` or simply switch to using ccmake.&lt;br /&gt;
&lt;br /&gt;
==Compiling with MPI==&lt;br /&gt;
To compile with MPI support add the following flags when running cmake on the command line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=mpif90 CC=mpicc cmake ../source -DCOMPILER_SWITCH=pgi -DWITH_MPI=yes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here -DCOMPILER_SWITCH=pgi assumes you&#039;re using the Portland &#039;&#039;pgi&#039;&#039; compiler. Make sure you have the correct modules loaded (in this case &#039;&#039;pgi&#039;&#039; and &#039;&#039;mpi-pgi&#039;&#039;), and that the particular mpi you want (in this case &#039;&#039;mpi-pgi&#039;&#039;) is listed before any other mpi&#039;s loaded (so that it has the highest priority). The modules can be loaded by typing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load pgi/64/&lt;br /&gt;
module load mpi/openmpi/pgi/64/1.6.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and you can check which modules are loaded and in which order/priority by the &#039;&#039;module list&#039;&#039; command. You may need to &#039;&#039;module unload &amp;lt;name&amp;gt;&#039;&#039; any other mpi&#039;s that are higher up in the list than the one you want. You can of course set the COMPILER_SWITCH and WITH_MPI flags in &#039;&#039;ccmake&#039;&#039; if you prefer.&lt;br /&gt;
&lt;br /&gt;
Note: It has been observed that pgi/64/15.1 leads to compilation errors, and for now, it is best to use pgi/64/14.9&lt;br /&gt;
&lt;br /&gt;
==Advanced mode - changing compiler flags with ccmake==&lt;br /&gt;
[[Image:Ccmakeadvanced.png|thumb|ccmake advanced mode|200px|right]]&lt;br /&gt;
&lt;br /&gt;
Although initially the &#039;&#039;ccmake&#039;&#039; GUI looks very simple, there is a lot going on under the hood. By pressing &#039;t&#039; you can enter &#039;Advanced mode&#039; which will show you all of the hidden options, for example the compiler flags that are being passed to &#039;&#039;make&#039;&#039; when you compile the code. You can also make changes to the flags here, for example if you would like to add &#039;-p&#039; to do  profiling. &lt;br /&gt;
&lt;br /&gt;
As with changing the build type, you simply select the field you&#039;d like to change using the arrow keys, press Return, make your changes and press Return again to save them. When you subsequently configure and generate as above, those altered flag will be used for the subsequent compilation.&lt;br /&gt;
&lt;br /&gt;
Note that these changes only apply in the build directory in which you make them.&lt;br /&gt;
&lt;br /&gt;
==Debugging runtime problems using gdb or valgrind==&lt;br /&gt;
If you are getting a segmentation fault, crash or other unexpected behaviour, you might want to run your job through a debugger like [http://www.gnu.org/software/gdb/ gdb] or [http://valgrind.org/ valgrind]. In order to maximise your chances of getting useful output, you should build a &#039;Debug&#039; version of the program you are having trouble. To do this, you can either change the &#039;&#039;CMAKE_BUILD_TYPE&#039;&#039; in &#039;&#039;ccmake&#039;&#039; to &#039;Debug&#039; (press Return, change &#039;Release&#039; to &#039;Debug&#039; and press Return again), or on the command line like so for GMIN with AMBER 9 using the Intel ifort compiler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then run the binary &#039;&#039;through&#039;&#039; gdb or valgrind as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
valgrind A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I won&#039;t cover debugging with these tools here as it&#039;s a science in itself! Do some Googling and ask for help as needed :)&lt;br /&gt;
&lt;br /&gt;
==Debugging compilation problems==&lt;br /&gt;
There are many ways to try and track down why your code is not compiling. Before you start changing compilers, building a &#039;Debug&#039; version or changing machines, you might want to try running make again with the &#039;&#039;VERBOSE&#039;&#039; option enabled. This will dump a lot of potentially useful output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VERBOSE=1 make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One possible gotcha: all .f and .f90 files in the relevant source directories will be compiled and added to a library. This is quite different from the old Makefile way of doing things, where source files were explicitly specified for compilation (via their corresponding .o file). So, if you are testing something by for instance copying code.f90 to code.myhack.f90 and code.orig.f90, then slightly editing a line or two of code.myhack.f90 and copying it back to code.f90 for use, this will probably cause linking problems due to multiply-defined subroutines (from all three files). The solution, if you must have alternative versions of the same file hanging round, is to differentiate the filenames by a suffix AFTER the .f[90] .&lt;br /&gt;
 &lt;br /&gt;
Another occasional issue is the unexplained compiler bug - a problem with the version of the compiler you happen to be using. You can can an idea for which compiler versions we expect to work by checking the Jenkins build-bot output, as described in the &#039;Seeing console output&#039; section of the [[Jenkins CI]] page. If you are using a different version of the compiler in question, consider swapping to the version Jenkins is using with &#039;module swap&#039;.&lt;br /&gt;
&lt;br /&gt;
If the error message you are getting doesn&#039;t make sense to you after some Googling, go and ask someone - we all have these problems. Things you can try first include trying a different compiler version, or an entirely different compiler e.g. pgi rather than ifort for example. You should bear in mind that as mentioned above, not all versions of each code will compile with every compiler. Make sure you&#039;re not trying to build something that isn&#039;t expected to work.&lt;br /&gt;
&lt;br /&gt;
==Extra command line build examples==&lt;br /&gt;
The below commands are absolutely not an exhaustive list, but should give you an idea of what is possible. You can use &#039;&#039;ccmake&#039;&#039; as described above to discover which variables (e.g. WITH_AMBER) can be manipulated on the command line like this. All of these examples assume your svn repository is set up in &#039;&#039;/home/CRSID/softwarewales&#039;&#039; - make the appropriate modifications if you have it elsewhere.&lt;br /&gt;
&lt;br /&gt;
===GMIN===&lt;br /&gt;
&#039;&#039;&#039;A12GMIN&#039;&#039;&#039; (GMIN with AMBER12) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_amber12&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER12=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35GMIN&#039;&#039;&#039; (GMIN with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAGMIN&#039;&#039;&#039; (GMIN leveraging GPU minimisation via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_cuda&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBGMIN&#039;&#039;&#039; (GMIN with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===OPTIM===&lt;br /&gt;
&#039;&#039;&#039;A9OPTIM&#039;&#039;&#039; (OPTIM with AMBER9) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_amber&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER9=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35OPTIM&#039;&#039;&#039; (OPTIM with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAOPTIM&#039;&#039;&#039; (OPTIM leveraging GPU via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_cuda5.5&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN and OPTIM with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBOPTIM&#039;&#039;&#039; (OPTIM with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===PATHSAMPLE===&lt;br /&gt;
There are very few options for [[PATHSAMPLE]] as we don&#039;t need to worry about interfacing with a particular potential. As a result, every binary is simply called &#039;&#039;PATHSAMPLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Using nagfor (the NAG fortran compiler - check you have the module loaded - very strict!):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/nagfor&lt;br /&gt;
cd !$&lt;br /&gt;
FC=nagfor cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pgi (much more generous with coding slips/non-standard uses):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/pgi&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring defaults - for developers==&lt;br /&gt;
&lt;br /&gt;
Fortran compilers and their corresponding default settings are all controlled by the file $SVN/CMakeModules/FindFORTRANCOMPILER.cmake ($SVN is your svn root directory). In particular, we may wish to edit the flags used for each set of compilers and build type. These are contained in the following block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
   message(&amp;quot;Setting initial values for compiler flags&amp;quot;)&lt;br /&gt;
   if(COMPILER_SWITCH MATCHES &amp;quot;pgi&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-Mextend&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3 -Munroll -Mnoframe&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Mdwarf3 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-Mfree&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;gfortran&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-ffixed-line-length-200 -ffree-line-length-0&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
#      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fimplicit-none -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;${CMAKE_Fortran_FLAGS_DEBUG} -fimplicit-none&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-ffree-form&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;nag&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -kind=byte -maxcontin=3000&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-mismatch_all -O4&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-C=all -mtrace=all -gline -g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING) # js850&amp;gt; is this ever used?&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;ifort&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -heap-arrays -assume byterecl&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
# Warnings about temporary argument creation and edit descriptor widths are disabled with the final flags.&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-C -g -traceback -debug full -check all,noarg_temp_created -diag-disable 8290,8291&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-debug all -check all -implicitnone -warn unused -fp-stack-check -ftrapuv -check pointers -check bounds&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   else()&lt;br /&gt;
      message(FATAL_ERROR &amp;quot;unknown comiler switch: ${COMPILER_SWITCH}&amp;quot;)&lt;br /&gt;
   endif()&lt;br /&gt;
    SET(COMPILER_FLAGS_WERE_SET yes CACHE TYPE INTERNAL)&lt;br /&gt;
endif(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main if/elseif blocks correspond to compiler switches. Inside these, there are the default flags for each of our build types (release, debug and debug_slow), which are configured using ccmake. These can be edited, if we wish to change the default behaviour (e.g. a recent addition of -check all,noarg_temp_created -diag-disable 8290,8291 to disable annoying warning messages for ifort).&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1794</id>
		<title>Compiling Wales Group codes using cmake</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1794"/>
		<updated>2022-09-09T14:02:37Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* OPTIM */ Added DFTBP examples.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cmake.org/ CMake] (Cross-platform Make) provides a simple, platform independent way for us to compile and test the group codebase. Dependencies are handled automatically, compilation can proceed in parallel to avoid long waits while testing changes and builds are done entirely outside of the source directory. It also enables us to use the [[Jenkins CI]] &#039;build bot&#039; system to automatically compile and test the code on a nightly basis - helping us catch troublesome commits before they affect other users. &lt;br /&gt;
&lt;br /&gt;
Although everything below refers to compiling [[GMIN]] with the Intel &#039;&#039;ifort&#039;&#039; compiler and AMBER9 - the exact same procedure works for [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
&lt;br /&gt;
Note that not every option for our codes is expected to actually compile with every compiler, for example, anything using CHARMM35/36 will not compile with &#039;&#039;nagfor&#039;&#039; or &#039;&#039;gfortran&#039;&#039;. This is nothing to do with our code - it&#039;s a CHARMM issue. You can get an idea for what should work by looking at the automated [[Jenkins CI]] builds.&lt;br /&gt;
&lt;br /&gt;
==Preparing to compile==&lt;br /&gt;
Before you get started, you need to ensure that the machine you are planning to compile on has cmake 2.8 or higher installed. You can check the current version like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake --version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The clusters have a module for cmake 3.0, which you can load using the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.0.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You also need to create a directory to build the code in. We suggest that you create a directory for the compiler you are using within the program directory, under a subdirectory called &#039;builds&#039; - for example for compiling GMIN with ifort, you would make a directory here:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
cd ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can call these directories whatever you like - but make sure it is clear to you what they contain! You might also want to check which version of the compiler you have loaded. This is important as the different clusters and workstations may have different default versions loaded, some of which might not work properly. You can check the compiler version currently loaded using the same &#039;--version&#039; flag we used for &#039;&#039;cmake&#039;&#039; above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ifort --version&lt;br /&gt;
ifort (IFORT) 12.1.3 20120212&lt;br /&gt;
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To load a different compiler, you can use the &#039;&#039;module load&#039;&#039; or &#039;&#039;module swap&#039;&#039; commands. A list of all available modules can be accessed using:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module av&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are having problems compiling, one of the first things to check is whether it works with a different version of the compiler!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: When compiling GMIN, if you are getting the error that there is no implicit type for ERFC in ewald.f90, try using a newer version of your compiler. This should be the built-in complementary error function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling using the ccmake GUI interface to set options==&lt;br /&gt;
[[Image:Ccmake.png|thumb|ccmake set up to compile A9GMIN|200px|right]]&lt;br /&gt;
&lt;br /&gt;
One advantage using cmake has over make is that we can use the simple ccmake GUI. This interface lets us set options like compiling with AMBER9, or CHARMM35, toggle between &#039;Release&#039; and &#039;Debug&#039; builds (see below) - and examine and alter the flags being uses for the compilation if we wish. Before we can run ccmake, we need to specify the compiler and run cmake in our build directory (e.g. softwarewales/GMIN/builds/ifort). We specify the &#039;&#039;&#039;F&#039;&#039;&#039;ortran &#039;&#039;&#039;C&#039;&#039;&#039;ompiler by setting the &#039;&#039;&#039;$FC&#039;&#039;&#039; environment variable (in this case the Intel Fortran compiler, ifort), and then run &#039;&#039;cmake&#039;&#039; (on the command line), passing it the relative location of the [[GMIN]] source directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake ../../source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you run &#039;&#039;ls&#039;&#039;, you will see some cmake files have been generated:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  modules&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now run &#039;&#039;ccmake&#039;&#039; to open the GUI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ccmake .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To navigate between options, use the arrow keys. Options can be toggled by pressing Return. To compile [[GMIN]] with AMBER9 (A9GMIN), we need to toggle the &#039;&#039;WITH_AMBER&#039;&#039; option &#039;&#039;ON&#039;&#039;. Once you have done this, you need to configure and generate appropriate cmake info. This is done by pressing &#039;c&#039; to configure, &#039;e&#039; to exit and then &#039;g&#039; to generate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: for some builds (CHARMM with DFTB and CUDAGMIN), you might need to configure, exit and generate twice to set all necessary options&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now compile A9GMIN in parallel as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;-j8&#039; flag here tells make to use up to 8 &#039;threads&#039; when building. For optimal performance, you should keep this slightly greater than the number of cores (CPUs) the node you are working on has. If all goes well, you should now have an A9GMIN binary in your build directory - congratulations! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linking Fortran executable A9GMIN&lt;br /&gt;
[100%] Built target A9GMIN&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------------------- 15:23:45&lt;br /&gt;
&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
A9GMIN          cmake_install.cmake   libcudadummylib.a  libmylapack.a  NAB&lt;br /&gt;
AMBER           display_version.f90   libdummylib.a      Makefile       nab_binaries_built&lt;br /&gt;
CMakeCache.txt  GMIN                  libgminlib.a       modules        porfuncs.f90&lt;br /&gt;
CMakeFiles      libamber12dummylib.a  libmyblas.a        n&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Plain [[GMIN]] is also built at the same time should you need it. You can move this into your ~/bin directory if you like, or anywhere else in your &#039;&#039;$PATH&#039;&#039; to make running it simple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: If you want to use OPTIM with the new C++ implementation of the NEB routine, you will need to obtain the source code for that separately. See [https://wikis.ch.cam.ac.uk/wales/wiki/index.php/OPTIM here] for instructions.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling by setting options on the command line==&lt;br /&gt;
If you know the options you&#039;d like to set already (you can see them all in ccmake), you can save some time by passing them directly to &#039;&#039;cmake&#039;&#039; on the command line, bypassing the need for &#039;&#039;ccmake&#039;&#039;. For example, to compile A9GMIN (GMIN with the AMBER9 interface) using the Intel ifort compiler, you would run the following commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &#039;../../source&#039; is the relative location of the GMIN source directory. You can find some more examples of compiling from the command line below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: Sometimes you may get error&#039;&#039;&#039; (for example, Fatal Error: Can&#039;t open module file &#039;someModule.mod&#039; for reading at (1): No such file or directory) when following this procedure. In that case there are three things you could try: make sure you are building in a new directory, if that does not help run `make VERBOSE=1` instead of `make -j8` or simply switch to using ccmake.&lt;br /&gt;
&lt;br /&gt;
==Compiling with MPI==&lt;br /&gt;
To compile with MPI support add the following flags when running cmake on the command line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=mpif90 CC=mpicc cmake ../source -DCOMPILER_SWITCH=pgi -DWITH_MPI=yes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here -DCOMPILER_SWITCH=pgi assumes you&#039;re using the Portland &#039;&#039;pgi&#039;&#039; compiler. Make sure you have the correct modules loaded (in this case &#039;&#039;pgi&#039;&#039; and &#039;&#039;mpi-pgi&#039;&#039;), and that the particular mpi you want (in this case &#039;&#039;mpi-pgi&#039;&#039;) is listed before any other mpi&#039;s loaded (so that it has the highest priority). The modules can be loaded by typing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load pgi/64/&lt;br /&gt;
module load mpi/openmpi/pgi/64/1.6.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and you can check which modules are loaded and in which order/priority by the &#039;&#039;module list&#039;&#039; command. You may need to &#039;&#039;module unload &amp;lt;name&amp;gt;&#039;&#039; any other mpi&#039;s that are higher up in the list than the one you want. You can of course set the COMPILER_SWITCH and WITH_MPI flags in &#039;&#039;ccmake&#039;&#039; if you prefer.&lt;br /&gt;
&lt;br /&gt;
Note: It has been observed that pgi/64/15.1 leads to compilation errors, and for now, it is best to use pgi/64/14.9&lt;br /&gt;
&lt;br /&gt;
==Advanced mode - changing compiler flags with ccmake==&lt;br /&gt;
[[Image:Ccmakeadvanced.png|thumb|ccmake advanced mode|200px|right]]&lt;br /&gt;
&lt;br /&gt;
Although initially the &#039;&#039;ccmake&#039;&#039; GUI looks very simple, there is a lot going on under the hood. By pressing &#039;t&#039; you can enter &#039;Advanced mode&#039; which will show you all of the hidden options, for example the compiler flags that are being passed to &#039;&#039;make&#039;&#039; when you compile the code. You can also make changes to the flags here, for example if you would like to add &#039;-p&#039; to do  profiling. &lt;br /&gt;
&lt;br /&gt;
As with changing the build type, you simply select the field you&#039;d like to change using the arrow keys, press Return, make your changes and press Return again to save them. When you subsequently configure and generate as above, those altered flag will be used for the subsequent compilation.&lt;br /&gt;
&lt;br /&gt;
Note that these changes only apply in the build directory in which you make them.&lt;br /&gt;
&lt;br /&gt;
==Debugging runtime problems using gdb or valgrind==&lt;br /&gt;
If you are getting a segmentation fault, crash or other unexpected behaviour, you might want to run your job through a debugger like [http://www.gnu.org/software/gdb/ gdb] or [http://valgrind.org/ valgrind]. In order to maximise your chances of getting useful output, you should build a &#039;Debug&#039; version of the program you are having trouble. To do this, you can either change the &#039;&#039;CMAKE_BUILD_TYPE&#039;&#039; in &#039;&#039;ccmake&#039;&#039; to &#039;Debug&#039; (press Return, change &#039;Release&#039; to &#039;Debug&#039; and press Return again), or on the command line like so for GMIN with AMBER 9 using the Intel ifort compiler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then run the binary &#039;&#039;through&#039;&#039; gdb or valgrind as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
valgrind A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I won&#039;t cover debugging with these tools here as it&#039;s a science in itself! Do some Googling and ask for help as needed :)&lt;br /&gt;
&lt;br /&gt;
==Debugging compilation problems==&lt;br /&gt;
There are many ways to try and track down why your code is not compiling. Before you start changing compilers, building a &#039;Debug&#039; version or changing machines, you might want to try running make again with the &#039;&#039;VERBOSE&#039;&#039; option enabled. This will dump a lot of potentially useful output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VERBOSE=1 make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One possible gotcha: all .f and .f90 files in the relevant source directories will be compiled and added to a library. This is quite different from the old Makefile way of doing things, where source files were explicitly specified for compilation (via their corresponding .o file). So, if you are testing something by for instance copying code.f90 to code.myhack.f90 and code.orig.f90, then slightly editing a line or two of code.myhack.f90 and copying it back to code.f90 for use, this will probably cause linking problems due to multiply-defined subroutines (from all three files). The solution, if you must have alternative versions of the same file hanging round, is to differentiate the filenames by a suffix AFTER the .f[90] .&lt;br /&gt;
 &lt;br /&gt;
Another occasional issue is the unexplained compiler bug - a problem with the version of the compiler you happen to be using. You can can an idea for which compiler versions we expect to work by checking the Jenkins build-bot output, as described in the &#039;Seeing console output&#039; section of the [[Jenkins CI]] page. If you are using a different version of the compiler in question, consider swapping to the version Jenkins is using with &#039;module swap&#039;.&lt;br /&gt;
&lt;br /&gt;
If the error message you are getting doesn&#039;t make sense to you after some Googling, go and ask someone - we all have these problems. Things you can try first include trying a different compiler version, or an entirely different compiler e.g. pgi rather than ifort for example. You should bear in mind that as mentioned above, not all versions of each code will compile with every compiler. Make sure you&#039;re not trying to build something that isn&#039;t expected to work.&lt;br /&gt;
&lt;br /&gt;
==Extra command line build examples==&lt;br /&gt;
The below commands are absolutely not an exhaustive list, but should give you an idea of what is possible. You can use &#039;&#039;ccmake&#039;&#039; as described above to discover which variables (e.g. WITH_AMBER) can be manipulated on the command line like this. All of these examples assume your svn repository is set up in &#039;&#039;/home/CRSID/svn&#039;&#039; - make the appropriate modifications if you have it elsewhere.&lt;br /&gt;
&lt;br /&gt;
===GMIN===&lt;br /&gt;
&#039;&#039;&#039;A12GMIN&#039;&#039;&#039; (GMIN with AMBER12) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_amber12&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER12=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35GMIN&#039;&#039;&#039; (GMIN with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAGMIN&#039;&#039;&#039; (GMIN leveraging GPU minimisation via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_cuda&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBGMIN&#039;&#039;&#039; (GMIN with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===OPTIM===&lt;br /&gt;
&#039;&#039;&#039;A9OPTIM&#039;&#039;&#039; (OPTIM with AMBER9) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_amber&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER9=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35OPTIM&#039;&#039;&#039; (OPTIM with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAOPTIM&#039;&#039;&#039; (OPTIM leveraging GPU via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_cuda5.5&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN and OPTIM with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBOPTIM&#039;&#039;&#039; (OPTIM with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===PATHSAMPLE===&lt;br /&gt;
There are very few options for [[PATHSAMPLE]] as we don&#039;t need to worry about interfacing with a particular potential. As a result, every binary is simply called &#039;&#039;PATHSAMPLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Using nagfor (the NAG fortran compiler - check you have the module loaded - very strict!):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/nagfor&lt;br /&gt;
cd !$&lt;br /&gt;
FC=nagfor cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pgi (much more generous with coding slips/non-standard uses):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/pgi&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring defaults - for developers==&lt;br /&gt;
&lt;br /&gt;
Fortran compilers and their corresponding default settings are all controlled by the file $SVN/CMakeModules/FindFORTRANCOMPILER.cmake ($SVN is your svn root directory). In particular, we may wish to edit the flags used for each set of compilers and build type. These are contained in the following block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
   message(&amp;quot;Setting initial values for compiler flags&amp;quot;)&lt;br /&gt;
   if(COMPILER_SWITCH MATCHES &amp;quot;pgi&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-Mextend&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3 -Munroll -Mnoframe&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Mdwarf3 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-Mfree&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;gfortran&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-ffixed-line-length-200 -ffree-line-length-0&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
#      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fimplicit-none -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;${CMAKE_Fortran_FLAGS_DEBUG} -fimplicit-none&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-ffree-form&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;nag&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -kind=byte -maxcontin=3000&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-mismatch_all -O4&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-C=all -mtrace=all -gline -g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING) # js850&amp;gt; is this ever used?&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;ifort&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -heap-arrays -assume byterecl&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
# Warnings about temporary argument creation and edit descriptor widths are disabled with the final flags.&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-C -g -traceback -debug full -check all,noarg_temp_created -diag-disable 8290,8291&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-debug all -check all -implicitnone -warn unused -fp-stack-check -ftrapuv -check pointers -check bounds&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   else()&lt;br /&gt;
      message(FATAL_ERROR &amp;quot;unknown comiler switch: ${COMPILER_SWITCH}&amp;quot;)&lt;br /&gt;
   endif()&lt;br /&gt;
    SET(COMPILER_FLAGS_WERE_SET yes CACHE TYPE INTERNAL)&lt;br /&gt;
endif(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main if/elseif blocks correspond to compiler switches. Inside these, there are the default flags for each of our build types (release, debug and debug_slow), which are configured using ccmake. These can be edited, if we wish to change the default behaviour (e.g. a recent addition of -check all,noarg_temp_created -diag-disable 8290,8291 to disable annoying warning messages for ifort).&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1793</id>
		<title>Compiling Wales Group codes using cmake</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Compiling_Wales_Group_codes_using_cmake&amp;diff=1793"/>
		<updated>2022-09-09T14:01:51Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* GMIN */ Added DFTBP examples.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://www.cmake.org/ CMake] (Cross-platform Make) provides a simple, platform independent way for us to compile and test the group codebase. Dependencies are handled automatically, compilation can proceed in parallel to avoid long waits while testing changes and builds are done entirely outside of the source directory. It also enables us to use the [[Jenkins CI]] &#039;build bot&#039; system to automatically compile and test the code on a nightly basis - helping us catch troublesome commits before they affect other users. &lt;br /&gt;
&lt;br /&gt;
Although everything below refers to compiling [[GMIN]] with the Intel &#039;&#039;ifort&#039;&#039; compiler and AMBER9 - the exact same procedure works for [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
&lt;br /&gt;
Note that not every option for our codes is expected to actually compile with every compiler, for example, anything using CHARMM35/36 will not compile with &#039;&#039;nagfor&#039;&#039; or &#039;&#039;gfortran&#039;&#039;. This is nothing to do with our code - it&#039;s a CHARMM issue. You can get an idea for what should work by looking at the automated [[Jenkins CI]] builds.&lt;br /&gt;
&lt;br /&gt;
==Preparing to compile==&lt;br /&gt;
Before you get started, you need to ensure that the machine you are planning to compile on has cmake 2.8 or higher installed. You can check the current version like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cmake --version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The clusters have a module for cmake 3.0, which you can load using the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.0.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You also need to create a directory to build the code in. We suggest that you create a directory for the compiler you are using within the program directory, under a subdirectory called &#039;builds&#039; - for example for compiling GMIN with ifort, you would make a directory here:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
cd ~/softwarewales/GMIN/builds/ifort&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can call these directories whatever you like - but make sure it is clear to you what they contain! You might also want to check which version of the compiler you have loaded. This is important as the different clusters and workstations may have different default versions loaded, some of which might not work properly. You can check the compiler version currently loaded using the same &#039;--version&#039; flag we used for &#039;&#039;cmake&#039;&#039; above:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ifort --version&lt;br /&gt;
ifort (IFORT) 12.1.3 20120212&lt;br /&gt;
Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To load a different compiler, you can use the &#039;&#039;module load&#039;&#039; or &#039;&#039;module swap&#039;&#039; commands. A list of all available modules can be accessed using:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module av&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you are having problems compiling, one of the first things to check is whether it works with a different version of the compiler!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: When compiling GMIN, if you are getting the error that there is no implicit type for ERFC in ewald.f90, try using a newer version of your compiler. This should be the built-in complementary error function.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling using the ccmake GUI interface to set options==&lt;br /&gt;
[[Image:Ccmake.png|thumb|ccmake set up to compile A9GMIN|200px|right]]&lt;br /&gt;
&lt;br /&gt;
One advantage using cmake has over make is that we can use the simple ccmake GUI. This interface lets us set options like compiling with AMBER9, or CHARMM35, toggle between &#039;Release&#039; and &#039;Debug&#039; builds (see below) - and examine and alter the flags being uses for the compilation if we wish. Before we can run ccmake, we need to specify the compiler and run cmake in our build directory (e.g. softwarewales/GMIN/builds/ifort). We specify the &#039;&#039;&#039;F&#039;&#039;&#039;ortran &#039;&#039;&#039;C&#039;&#039;&#039;ompiler by setting the &#039;&#039;&#039;$FC&#039;&#039;&#039; environment variable (in this case the Intel Fortran compiler, ifort), and then run &#039;&#039;cmake&#039;&#039; (on the command line), passing it the relative location of the [[GMIN]] source directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake ../../source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you run &#039;&#039;ls&#039;&#039;, you will see some cmake files have been generated:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile  modules&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can now run &#039;&#039;ccmake&#039;&#039; to open the GUI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ccmake .&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To navigate between options, use the arrow keys. Options can be toggled by pressing Return. To compile [[GMIN]] with AMBER9 (A9GMIN), we need to toggle the &#039;&#039;WITH_AMBER&#039;&#039; option &#039;&#039;ON&#039;&#039;. Once you have done this, you need to configure and generate appropriate cmake info. This is done by pressing &#039;c&#039; to configure, &#039;e&#039; to exit and then &#039;g&#039; to generate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: for some builds (CHARMM with DFTB and CUDAGMIN), you might need to configure, exit and generate twice to set all necessary options&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can now compile A9GMIN in parallel as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;-j8&#039; flag here tells make to use up to 8 &#039;threads&#039; when building. For optimal performance, you should keep this slightly greater than the number of cores (CPUs) the node you are working on has. If all goes well, you should now have an A9GMIN binary in your build directory - congratulations! &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Linking Fortran executable A9GMIN&lt;br /&gt;
[100%] Built target A9GMIN&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------------------- 15:23:45&lt;br /&gt;
&lt;br /&gt;
csw34@sinister:~/softwarewales/GMIN/builds/ifort&amp;gt; ls&lt;br /&gt;
A9GMIN          cmake_install.cmake   libcudadummylib.a  libmylapack.a  NAB&lt;br /&gt;
AMBER           display_version.f90   libdummylib.a      Makefile       nab_binaries_built&lt;br /&gt;
CMakeCache.txt  GMIN                  libgminlib.a       modules        porfuncs.f90&lt;br /&gt;
CMakeFiles      libamber12dummylib.a  libmyblas.a        n&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Plain [[GMIN]] is also built at the same time should you need it. You can move this into your ~/bin directory if you like, or anywhere else in your &#039;&#039;$PATH&#039;&#039; to make running it simple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: If you want to use OPTIM with the new C++ implementation of the NEB routine, you will need to obtain the source code for that separately. See [https://wikis.ch.cam.ac.uk/wales/wiki/index.php/OPTIM here] for instructions.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Compiling by setting options on the command line==&lt;br /&gt;
If you know the options you&#039;d like to set already (you can see them all in ccmake), you can save some time by passing them directly to &#039;&#039;cmake&#039;&#039; on the command line, bypassing the need for &#039;&#039;ccmake&#039;&#039;. For example, to compile A9GMIN (GMIN with the AMBER9 interface) using the Intel ifort compiler, you would run the following commands:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &#039;../../source&#039; is the relative location of the GMIN source directory. You can find some more examples of compiling from the command line below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: Sometimes you may get error&#039;&#039;&#039; (for example, Fatal Error: Can&#039;t open module file &#039;someModule.mod&#039; for reading at (1): No such file or directory) when following this procedure. In that case there are three things you could try: make sure you are building in a new directory, if that does not help run `make VERBOSE=1` instead of `make -j8` or simply switch to using ccmake.&lt;br /&gt;
&lt;br /&gt;
==Compiling with MPI==&lt;br /&gt;
To compile with MPI support add the following flags when running cmake on the command line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=mpif90 CC=mpicc cmake ../source -DCOMPILER_SWITCH=pgi -DWITH_MPI=yes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here -DCOMPILER_SWITCH=pgi assumes you&#039;re using the Portland &#039;&#039;pgi&#039;&#039; compiler. Make sure you have the correct modules loaded (in this case &#039;&#039;pgi&#039;&#039; and &#039;&#039;mpi-pgi&#039;&#039;), and that the particular mpi you want (in this case &#039;&#039;mpi-pgi&#039;&#039;) is listed before any other mpi&#039;s loaded (so that it has the highest priority). The modules can be loaded by typing:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load pgi/64/&lt;br /&gt;
module load mpi/openmpi/pgi/64/1.6.3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and you can check which modules are loaded and in which order/priority by the &#039;&#039;module list&#039;&#039; command. You may need to &#039;&#039;module unload &amp;lt;name&amp;gt;&#039;&#039; any other mpi&#039;s that are higher up in the list than the one you want. You can of course set the COMPILER_SWITCH and WITH_MPI flags in &#039;&#039;ccmake&#039;&#039; if you prefer.&lt;br /&gt;
&lt;br /&gt;
Note: It has been observed that pgi/64/15.1 leads to compilation errors, and for now, it is best to use pgi/64/14.9&lt;br /&gt;
&lt;br /&gt;
==Advanced mode - changing compiler flags with ccmake==&lt;br /&gt;
[[Image:Ccmakeadvanced.png|thumb|ccmake advanced mode|200px|right]]&lt;br /&gt;
&lt;br /&gt;
Although initially the &#039;&#039;ccmake&#039;&#039; GUI looks very simple, there is a lot going on under the hood. By pressing &#039;t&#039; you can enter &#039;Advanced mode&#039; which will show you all of the hidden options, for example the compiler flags that are being passed to &#039;&#039;make&#039;&#039; when you compile the code. You can also make changes to the flags here, for example if you would like to add &#039;-p&#039; to do  profiling. &lt;br /&gt;
&lt;br /&gt;
As with changing the build type, you simply select the field you&#039;d like to change using the arrow keys, press Return, make your changes and press Return again to save them. When you subsequently configure and generate as above, those altered flag will be used for the subsequent compilation.&lt;br /&gt;
&lt;br /&gt;
Note that these changes only apply in the build directory in which you make them.&lt;br /&gt;
&lt;br /&gt;
==Debugging runtime problems using gdb or valgrind==&lt;br /&gt;
If you are getting a segmentation fault, crash or other unexpected behaviour, you might want to run your job through a debugger like [http://www.gnu.org/software/gdb/ gdb] or [http://valgrind.org/ valgrind]. In order to maximise your chances of getting useful output, you should build a &#039;Debug&#039; version of the program you are having trouble. To do this, you can either change the &#039;&#039;CMAKE_BUILD_TYPE&#039;&#039; in &#039;&#039;ccmake&#039;&#039; to &#039;Debug&#039; (press Return, change &#039;Release&#039; to &#039;Debug&#039; and press Return again), or on the command line like so for GMIN with AMBER 9 using the Intel ifort compiler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
FC=ifort cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_AMBER=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then run the binary &#039;&#039;through&#039;&#039; gdb or valgrind as follows:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
gdb A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
valgrind A9GMIN&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I won&#039;t cover debugging with these tools here as it&#039;s a science in itself! Do some Googling and ask for help as needed :)&lt;br /&gt;
&lt;br /&gt;
==Debugging compilation problems==&lt;br /&gt;
There are many ways to try and track down why your code is not compiling. Before you start changing compilers, building a &#039;Debug&#039; version or changing machines, you might want to try running make again with the &#039;&#039;VERBOSE&#039;&#039; option enabled. This will dump a lot of potentially useful output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
VERBOSE=1 make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One possible gotcha: all .f and .f90 files in the relevant source directories will be compiled and added to a library. This is quite different from the old Makefile way of doing things, where source files were explicitly specified for compilation (via their corresponding .o file). So, if you are testing something by for instance copying code.f90 to code.myhack.f90 and code.orig.f90, then slightly editing a line or two of code.myhack.f90 and copying it back to code.f90 for use, this will probably cause linking problems due to multiply-defined subroutines (from all three files). The solution, if you must have alternative versions of the same file hanging round, is to differentiate the filenames by a suffix AFTER the .f[90] .&lt;br /&gt;
 &lt;br /&gt;
Another occasional issue is the unexplained compiler bug - a problem with the version of the compiler you happen to be using. You can can an idea for which compiler versions we expect to work by checking the Jenkins build-bot output, as described in the &#039;Seeing console output&#039; section of the [[Jenkins CI]] page. If you are using a different version of the compiler in question, consider swapping to the version Jenkins is using with &#039;module swap&#039;.&lt;br /&gt;
&lt;br /&gt;
If the error message you are getting doesn&#039;t make sense to you after some Googling, go and ask someone - we all have these problems. Things you can try first include trying a different compiler version, or an entirely different compiler e.g. pgi rather than ifort for example. You should bear in mind that as mentioned above, not all versions of each code will compile with every compiler. Make sure you&#039;re not trying to build something that isn&#039;t expected to work.&lt;br /&gt;
&lt;br /&gt;
==Extra command line build examples==&lt;br /&gt;
The below commands are absolutely not an exhaustive list, but should give you an idea of what is possible. You can use &#039;&#039;ccmake&#039;&#039; as described above to discover which variables (e.g. WITH_AMBER) can be manipulated on the command line like this. All of these examples assume your svn repository is set up in &#039;&#039;/home/CRSID/svn&#039;&#039; - make the appropriate modifications if you have it elsewhere.&lt;br /&gt;
&lt;br /&gt;
===GMIN===&lt;br /&gt;
&#039;&#039;&#039;A12GMIN&#039;&#039;&#039; (GMIN with AMBER12) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_amber12&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER12=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35GMIN&#039;&#039;&#039; (GMIN with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAGMIN&#039;&#039;&#039; (GMIN leveraging GPU minimisation via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_cuda&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DFTBGMIN&#039;&#039;&#039; (GMIN with DFTBP) using Intel on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load mkl/64/2022/0/0 cmake/3.23.2 ifort/64/2020/4/304&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/ifort_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc CXX=icc cmake ../../source -DWITH_DFTBP=yes&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or using GCC on nest:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cmake/3.23.2 gcc/12.2.0&lt;br /&gt;
mkdir -p ~/softwarewales/GMIN/builds/gfortran_dftbp&lt;br /&gt;
cd !$&lt;br /&gt;
cmake ../../source -DWITH_DFTBP=yes -DWITH_MYBLAS=no -DBLAS_LIBRARIES=/usr/lib64/libopenblas.so.0&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===OPTIM===&lt;br /&gt;
&#039;&#039;&#039;A9OPTIM&#039;&#039;&#039; (OPTIM with AMBER9) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_amber&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort cmake -DWITH_AMBER9=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;C35OPTIM&#039;&#039;&#039; (OPTIM with CHARMM 35) using pgi:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/pgi_charmm35&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake -DWITH_CHARMM35=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CUDAOPTIM&#039;&#039;&#039; (OPTIM leveraging GPU via the AMBER 12 interface) using ifort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
module load cuda/5.5&lt;br /&gt;
mkdir -p ~/softwarewales/OPTIM/builds/ifort_cuda5.5&lt;br /&gt;
cd !$&lt;br /&gt;
FC=ifort CC=icc cmake -DWITH_CUDA=1 ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will only work on machines with specific NVIDIA GPUs, for example when submitting jobs on the pat cluster. There is some additional information on the [[Using GMIN and OPTIM with GPUs]] page.&lt;br /&gt;
&lt;br /&gt;
===PATHSAMPLE===&lt;br /&gt;
There are very few options for [[PATHSAMPLE]] as we don&#039;t need to worry about interfacing with a particular potential. As a result, every binary is simply called &#039;&#039;PATHSAMPLE&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Using nagfor (the NAG fortran compiler - check you have the module loaded - very strict!):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/nagfor&lt;br /&gt;
cd !$&lt;br /&gt;
FC=nagfor cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using pgi (much more generous with coding slips/non-standard uses):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/softwarewales/PATHSAMPLE/builds/pgi&lt;br /&gt;
cd !$&lt;br /&gt;
FC=pgf90 cmake ../../source&lt;br /&gt;
make -j8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring defaults - for developers==&lt;br /&gt;
&lt;br /&gt;
Fortran compilers and their corresponding default settings are all controlled by the file $SVN/CMakeModules/FindFORTRANCOMPILER.cmake ($SVN is your svn root directory). In particular, we may wish to edit the flags used for each set of compilers and build type. These are contained in the following block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
   message(&amp;quot;Setting initial values for compiler flags&amp;quot;)&lt;br /&gt;
   if(COMPILER_SWITCH MATCHES &amp;quot;pgi&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-Mextend&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3 -Munroll -Mnoframe&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-Mextend -C -g -gopt -Mbounds -Mchkfpstk -Mchkptr -Mchkstk -Mcoff -Mdwarf1 -Mdwarf2 -Mdwarf3 -Melf -Mpgicoff -traceback&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-Mfree&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;gfortran&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-ffixed-line-length-200 -ffree-line-length-0&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
#      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fimplicit-none -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -fbounds-check -Wuninitialized -O -ftrapv -fno-automatic&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;${CMAKE_Fortran_FLAGS_DEBUG} -fimplicit-none&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-ffree-form&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;nag&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -kind=byte -maxcontin=3000&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-mismatch_all -O4&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-C=all -mtrace=all -gline -g -mismatch_all -ieee=stop&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING) # js850&amp;gt; is this ever used?&lt;br /&gt;
   elseif(COMPILER_SWITCH MATCHES &amp;quot;ifort&amp;quot;)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS &amp;quot;-132 -heap-arrays -assume byterecl&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_RELEASE &amp;quot;-O3&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
# Warnings about temporary argument creation and edit descriptor widths are disabled with the final flags.&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG &amp;quot;-C -g -traceback -debug full -check all,noarg_temp_created -diag-disable 8290,8291&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (CMAKE_Fortran_FLAGS_DEBUG_SLOW &amp;quot;-debug all -check all -implicitnone -warn unused -fp-stack-check -ftrapuv -check pointers -check bounds&amp;quot; CACHE TYPE STRING FORCE)&lt;br /&gt;
      set (FORTRAN_FREEFORM_FLAG &amp;quot;-free&amp;quot; CACHE TYPE STRING)&lt;br /&gt;
   else()&lt;br /&gt;
      message(FATAL_ERROR &amp;quot;unknown comiler switch: ${COMPILER_SWITCH}&amp;quot;)&lt;br /&gt;
   endif()&lt;br /&gt;
    SET(COMPILER_FLAGS_WERE_SET yes CACHE TYPE INTERNAL)&lt;br /&gt;
endif(NOT COMPILER_FLAGS_WERE_SET)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main if/elseif blocks correspond to compiler switches. Inside these, there are the default flags for each of our build types (release, debug and debug_slow), which are configured using ccmake. These can be edited, if we wish to change the default behaviour (e.g. a recent addition of -check all,noarg_temp_created -diag-disable 8290,8291 to disable annoying warning messages for ifort).&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1792</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1792"/>
		<updated>2022-07-05T11:32:24Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Useful commands to know */  Added local branch cleaning.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;br /&gt;
&lt;br /&gt;
  $ git fetch -p &amp;amp;&amp;amp; for branch in $(git branch -vv | grep &#039;: gone]&#039; | awk &#039;{print $1}&#039;); do git branch -D $branch; done&lt;br /&gt;
&lt;br /&gt;
Delete all local branches that do not exist on GitLab. This command is useful to periodically clean up local branches after they have been merged and deleted on GitLab. Warning: do not run this command if you&#039;ve created a new local branch and not yet pushed it to GitLab.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1791</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1791"/>
		<updated>2022-03-22T13:24:23Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Tidied up LFS installation information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. If you get the error message&lt;br /&gt;
&lt;br /&gt;
  Error: failed to call git rev-parse --git-dir: exit status 128 : fatal: .git&lt;br /&gt;
&lt;br /&gt;
then try&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install --skip-repo&lt;br /&gt;
&lt;br /&gt;
instead. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1752</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1752"/>
		<updated>2021-04-30T10:40:11Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Basic Workflow */ Added information on git stash.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If other people have changed files you are working on, the pull will fail with an informative message. In this case, run&lt;br /&gt;
&lt;br /&gt;
  $ git stash&lt;br /&gt;
&lt;br /&gt;
which sets aside your local changes. Try the pull again, which should now succeed. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git stash pop&lt;br /&gt;
&lt;br /&gt;
to reapply your local changes to the updated repository. The merge will usually happen automatically, but sometimes you will need to resolve conflicts yourself.&lt;br /&gt;
&lt;br /&gt;
Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1751</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1751"/>
		<updated>2021-04-30T10:37:25Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Writing a Paper */ Slightly adjusted example workflow.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add. You will need to add them individually however, with &lt;br /&gt;
  $ git add -f filename &lt;br /&gt;
and cannot add all files at the same time (i.e. using git add -A).&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1748</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1748"/>
		<updated>2021-03-25T16:23:45Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Useful commands to know */ Corrected git clean&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean -f&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1747</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1747"/>
		<updated>2021-03-25T16:23:28Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Useful commands to know */ Added git clean.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;br /&gt;
&lt;br /&gt;
  $ git clean&lt;br /&gt;
&lt;br /&gt;
Throw away all untracked files. They will be deleted. Run with -n rather than -f to see which files would be deleted, but without actually doing anything.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1746</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1746"/>
		<updated>2021-03-23T16:05:53Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Writing a Paper */ Leave out LaTeX intermediate files.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
Do not add intermediate LaTeX files (.aux, .log, etc.) to the repository. Do not add your .dvi/.ps/.pdf document either. These extensions are all specified in the .gitignore file for the papers repository, so they will not show up with git status. If you are using .pdf or .ps for your images, you should still be able to add them with git add.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the Merge button and your branch will be merged into master. Just &#039;Approve&#039; from the reviewer won&#039;t usually be enough because you probably don&#039;t have permission to write to Master and hence cannot merge your new branch into master yourself. Once it has been merged, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1741</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1741"/>
		<updated>2021-02-12T12:56:44Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Initial Checkout */ Added information on setting name and email address.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
You should also tell Git your name and email address. Git will record these in the commit logs so other users will know who to complain to when a commit breaks everything. Run&lt;br /&gt;
&lt;br /&gt;
  $ git config --global user.name &amp;quot;An Other&amp;quot;&lt;br /&gt;
  $ git config --global user.email &amp;quot;ao123@cam.ac.uk&amp;quot;&lt;br /&gt;
&lt;br /&gt;
replacing the name and email address in quotes as appropriate.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. Once it has been accepted, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1740</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1740"/>
		<updated>2021-02-03T14:29:26Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Working on the group code */ Updates to merging workflow.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You need to test that your changes function with the new changes to master, so first you need to merge in master:&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git merge master&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The merge command merges changes that have been made to the master branch to your branch. It creates new commits, that you then push to the remote of your branch.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. Make sure you tick the boxes to delete the feature branch after the request is accepted, and to squash your branch into one commit. These options help keep the remote repository and history clean. You can edit the commit message for the one commit that will be created: by default it will be the name of your branch. The person you assign to will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. Once it has been accepted, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made. You might like to check that your new feature is in the master branch files before deleting your branch. If something has gone wrong and you delete your branch before the changes are in master, it is possible to recover, as the commits won&#039;t actually be deleted from the remote for a few weeks, but the recovery is an advanced topic that is best avoided.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1739</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1739"/>
		<updated>2021-01-19T11:06:11Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Installing git LFS */ Updated how to check whether the LFS clone succeeded.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Replace 2.0.0 with whatever the newest available version of git is. Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. After you have cloned the repository, you should inspect the LFS files to make sure the clone worked correctly. You can see a list of the files in .gitattributes in the repository root directory. A good file to check might be THESES/PHD/ChrisWhittlestonPhD.pdf. If this file is a PDF of several megabytes, then the LFS succeeded. If it is a small plaintext file containing a URL, the LFS clone did not succeed.&lt;br /&gt;
&lt;br /&gt;
If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1736</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1736"/>
		<updated>2021-01-04T13:32:26Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Installing git LFS */ Added module load information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. If you are using a department managed workstation, or any cluster other than rogue or nest, you will need to load a newer version of git:&lt;br /&gt;
&lt;br /&gt;
  $ module load git/2.0.0&lt;br /&gt;
&lt;br /&gt;
Or, on your personal Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Whatever computer you are using, then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. When you clone the repository, make sure that you see a line that starts with&lt;br /&gt;
&lt;br /&gt;
  Filtering content:&lt;br /&gt;
&lt;br /&gt;
in the terminal output. If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1735</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1735"/>
		<updated>2020-12-23T16:13:31Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Working on the group code */ Added instructions for large files.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. On a Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. When you clone the repository, make sure that you see a line that starts with&lt;br /&gt;
&lt;br /&gt;
  Filtering content:&lt;br /&gt;
&lt;br /&gt;
in the terminal output. If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
===Large Files===&lt;br /&gt;
&lt;br /&gt;
If any new file you are adding is large (&amp;gt;10MB), it should be stored on git LFS, rather than as a normal file. Fortunately, this is easy to do for new files. If you have already committed a large file and would now like to change it, you have a very complicated process ahead. The best instructions the author could find when doing this in the initial repository migration were here https://stackoverflow.com/questions/60995429/gradually-converting-a-repo-to-use-git-lfs-for-certain-files-one-file-at-a-time in the question, with the caveat that the bfg utility does not work and it was necessary to use git filter-branch as described here https://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository instead. Note this process will delete the history of your existing file and it will only appear from the most recent commit. It may be possible to adjust this with a git rebase, but the author has not investigated.&lt;br /&gt;
&lt;br /&gt;
Anyway, if you haven&#039;t yet committed your large file, you simply need to run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs track &amp;quot;&amp;lt;path-to-file&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which informs git that this file is to be uploaded using LFS. This command edits the file .gitattributes, which will also need to be added to your commit. If you make a mistake, you can edit .gitattributes manually. You can see some examples as well as the current list of files that are uploaded with LFS in .gitattributes. As you can see from inspecting the file, it is also possible to use wildcards (&#039;*&#039;) to specify multiple files at once. Be careful with your rules though: the rule is applied over all files, so if you add a rule for &#039;myfile.f90&#039; and somewhere else in the repository there is another file with the same name, it will now also be uploaded with LFS. This can be useful for specifying, for example, all .mp4 files in the whole repository, with &amp;quot;*.mp4&amp;quot;. However, if you really want just a specific file, specify the path from the repository root, for example &amp;quot;OPTIM/source/myfile.f90&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1734</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1734"/>
		<updated>2020-12-23T16:02:43Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Added information on git LFS&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Installing git LFS==&lt;br /&gt;
&lt;br /&gt;
Our software repository (git@gitlab.developers.cam.ac.uk:ch/wales/softwarewales.git) uses git Large File Storage (LFS) to manage some of the larger files. You must have the git LFS addon installed and initialised before cloning the software repository. If you do not, the clone will appear to succeed, but you will be missing some files. On a Ubuntu machine, run&lt;br /&gt;
&lt;br /&gt;
  $ sudo apt-get install git-lfs&lt;br /&gt;
&lt;br /&gt;
to install the necessary package. Then run&lt;br /&gt;
&lt;br /&gt;
  $ git lfs install&lt;br /&gt;
&lt;br /&gt;
to inform git about the new LFS addon. This command only needs to be run once on each machine you intend to clone the software repository on. When you clone the repository, make sure that you see a line that starts with&lt;br /&gt;
&lt;br /&gt;
  Filtering content:&lt;br /&gt;
&lt;br /&gt;
in the terminal output. If you have already cloned the repository before installing the LFS addon, you will need to clone again (a pull will not suffice).&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1733</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1733"/>
		<updated>2020-12-16T10:15:33Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Writing a Paper */ Corrected pulling order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git pull&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by committing, pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1732</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1732"/>
		<updated>2020-12-16T10:14:07Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Basic Workflow */ More details on git pull.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every push you make. One notable difference from updating in svn is that git will not merge other people&#039;s changes with files you have changed since your last commit. If you need to merge with files you are working on, do a commit (but not a push) first, then a pull. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1731</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1731"/>
		<updated>2020-12-10T17:47:00Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Initial Checkout */ Added warning against using https&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab, eg. [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard (don&#039;t use the &#039;clone with HTTPS&#039; link, or you will have to type your username and password every time). In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1730</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1730"/>
		<updated>2020-12-09T22:08:29Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Initial Checkout */ Typo fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard. In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1729</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1729"/>
		<updated>2020-12-09T21:54:02Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Setting up SSH access */ Added information on using rsa rather than ed25519&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (default location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
Some users have reported problems with using ed25519. RSA is available as an alternative. Generate an RSA key with&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t rsa -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
which will be saved by default at ~/.ssh/id_rsa.pub. Follow the same steps as above to add your public key to Gitlab.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard. In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing, the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1728</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1728"/>
		<updated>2020-12-09T18:19:33Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Fixed broken coding standards link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (defualt location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard. In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing, the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([https://wikis.ch.cam.ac.uk/wales/wiki/index.php/Wales_Group_Fortran_conventions_for_group_software here]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Comprehensive_Contents_Page&amp;diff=1726</id>
		<title>Comprehensive Contents Page</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Comprehensive_Contents_Page&amp;diff=1726"/>
		<updated>2020-09-28T10:09:54Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Acquiring and compiling the group software */ Link to Git page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is designed to organise all of the pages on this wiki, as well as provide other useful links. Note that some pages may appear under more than one heading.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
[[Wales Group]] provides good step-by-step instructions. Relevant pages are:&lt;br /&gt;
&lt;br /&gt;
=== Acquiring and compiling the group software ===&lt;br /&gt;
* [[SVN setup]]&lt;br /&gt;
* [[Git Workflow]]&lt;br /&gt;
* [[Wales Group Version control]] - to keep the code standardised.&lt;br /&gt;
* Theory Sector [http://wwmm.ch.cam.ac.uk/wikis/cuc3/index.php/SVN_Page SVN Page] - some useful general information on SVN commands.&lt;br /&gt;
* [[Compiling Wales Group codes using cmake]] - CMake (Cross-platform Make) allows us to compile and test the group codebase regardless of platform. This page provides crucial information how to compile using cmake.&lt;br /&gt;
* [[ElaborateDiff]]&lt;br /&gt;
&lt;br /&gt;
=== Maintaining code health ===&lt;br /&gt;
* [[Jenkins CI]] - explains Jenkins, which we use to download our code and compile each of our targets with each of the compilers every night.&lt;br /&gt;
* https://wales-jenkins.ch.cam.ac.uk/ - log for our Jenkins tests.&lt;br /&gt;
* [[Branching and Merging]]&lt;br /&gt;
* [[Cmake interface building]]&lt;br /&gt;
* [[Installing python modules]]&lt;br /&gt;
* [[Revamping the modules system]]&lt;br /&gt;
&lt;br /&gt;
=== Collaborators without access to the SVN repository ===&lt;br /&gt;
For licensing reasons, some code cannot be included in the Wales Group public tarball.&lt;br /&gt;
* http://www-wales.ch.cam.ac.uk/svn.tar.bz2 - Wales group public tarball. Includes [[GMIN]], [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
If a collaborator has a [[CHARMM]] or [[AMBER]] licence, we do maintain separate tarballs which include the [[CHARMM]], [[AMBER]] and [[CHARMM]]+[[AMBER]] source and interfaces. These are not linked anywhere on the website and require a username (&#039;&#039;&#039;wales&#039;&#039;&#039;) and password (&#039;&#039;&#039;group&#039;&#039;&#039;) to download:&lt;br /&gt;
&lt;br /&gt;
* [http://www-wales.ch.cam.ac.uk/CHARMM/svn.CHARMM.tar.bz2 CHARMM]&lt;br /&gt;
* [http://www-wales.ch.cam.ac.uk/AMBER/svn.AMBER.tar.bz2 AMBER]&lt;br /&gt;
* [http://www-wales.ch.cam.ac.uk/both/svn.both.tar.bz2 AMBER+CHARMM]&lt;br /&gt;
&lt;br /&gt;
=== Running on Windows ===&lt;br /&gt;
Not particularly recommended.&lt;br /&gt;
* [[Running Wales Group software on Windows 7]]&lt;br /&gt;
&lt;br /&gt;
== Wales Group Programs ==&lt;br /&gt;
&lt;br /&gt;
=== Programs ===&lt;br /&gt;
* [[GMIN]]: A program for finding global minima and calculating thermodynamic properties from basin-sampling.&lt;br /&gt;
* [[OPTIM]]: A program for optimizing geometries and calculating reaction pathways.&lt;br /&gt;
* [[PATHSAMPLE]]: A driver for OPTIM to create stationary point databases using discrete path sampling and perform kinetic analysis.&lt;br /&gt;
* [[Pele]]: Python energy landscape explorer. A pythonic rewrite of some core functionality of GMIN, OPTIM, and PATHSAMPLE. Can be very useful for visualizing your system and for rapidly implementing and testing new ideas.&lt;br /&gt;
&lt;br /&gt;
=== Curated Examples ===&lt;br /&gt;
* https://github.com/wales-group/examples - set of tutorials detailing how to use GMIN, OPTIM and PATHSAMPLE. Essential for beginners.&lt;br /&gt;
* http://www-wales.ch.cam.ac.uk/VM/Wales_Group_VM.ova - Pre-prepared teaching virtual machine. This contains the code and examples.&lt;br /&gt;
* https://www.virtualbox.org/wiki/Downloads - This is required if using the VM above.&lt;br /&gt;
* https://github.com/wales-group/examples.git - Alternatively, you can run the examples on your own machine. To get hold of the relevant files:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone https://github.com/wales-group/examples.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Useful Notes on Wales Group Programs and Subroutines ==&lt;br /&gt;
=== [[GMIN]] ===&lt;br /&gt;
* [[Adding a model to GMIN]] - rough outline of the subroutines that need to be changed to add a new model to GMIN&lt;br /&gt;
* [[Compiling Wales Group codes using cmake | Compiling GMIN using cmake ]]&lt;br /&gt;
* [[Selecting search parameters for GMIN]]&lt;br /&gt;
* [[Global optimization of biomolecules using CHARMM]]&lt;br /&gt;
* [[Global optimization of biomolecules using AMBER9]]&lt;br /&gt;
* [[Global optimization of biomolecules using AMBER9 with Structural Restraints]]&lt;br /&gt;
* [[Calculating binding free energy using the FSA method]]&lt;br /&gt;
* [[Restarting a GMIN run from a dump file]]&lt;br /&gt;
* [[Using the implicit membrane model IMM1]]&lt;br /&gt;
* [[Running a Go model with the AMHGMIN]]&lt;br /&gt;
* [[Running a G\=o model with the AMHGMIN]]&lt;br /&gt;
* [[Ligand binding-mode searches with HBONDMATRIX]]&lt;br /&gt;
* [[Compiling and using GMIN with QUIP]]&lt;br /&gt;
* [[Using GMIN and OPTIM with GPUs]]&lt;br /&gt;
* [[Using GMIN to generate endpoints]]&lt;br /&gt;
* [[Using GMIN to generate endpoints (CHARMM)]]&lt;br /&gt;
* [[Generating a GMIN Eclipse project]]&lt;br /&gt;
* [[Mutational BH steps]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[DMAGMIN setup]]&lt;br /&gt;
* [[Keywords]]&lt;br /&gt;
* [[PYGMIN &amp;amp; DMACRYS]]&lt;br /&gt;
* [[Rotamer moves in AMBER]]&lt;br /&gt;
* [[Python interface for GMIN/OPTIM]]&lt;br /&gt;
&lt;br /&gt;
==== Scripts ====&lt;br /&gt;
* [[makerestart]]: A bash script to automatically set up a GMIN restart run&lt;br /&gt;
* [[progress]] A bash script to tell you the % completion of a GMIN job and give an estimated time remaining&lt;br /&gt;
&lt;br /&gt;
==== Useful info for coding GMIN ====&lt;br /&gt;
* [[Program flow]] - contains information about what the various files in GMIN do and what order they&#039;re called. &lt;br /&gt;
* [[amberinterface]]&lt;br /&gt;
&lt;br /&gt;
==== Projects ====&lt;br /&gt;
* [[GMIN MOVES module]]&lt;br /&gt;
* [[GMIN SANITY module]]&lt;br /&gt;
* [[GMIN TESTS module]]&lt;br /&gt;
* [[CAMSHIFT]]&lt;br /&gt;
&lt;br /&gt;
=== [[OPTIM]] ===&lt;br /&gt;
* [[Adding a model to OPTIM]] - rough outline of the subrounties that need to be changed to add a new model to OPTIM&lt;br /&gt;
* [[Adding partially finished OPTIM stationary points to a PATHSAMPLE database]]&lt;br /&gt;
* [[perm-pdb.py]]: A python program that creates a &#039;&#039;perm.allow&#039;&#039; file for use with [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
* [[visualising normal modes using VMD and OPTIM]]&lt;br /&gt;
* [[Compiling Wales Group codes using cmake | Compiling OPTIM using cmake ]]&lt;br /&gt;
* [[OPTIM/Q-Chem Tutorial]]&lt;br /&gt;
* [[OPTIM and PY ellipsoids tutorial]]&lt;br /&gt;
* [[OPTIM output files]]&lt;br /&gt;
* [[Minimizing a structure using OPTIM and AMBER9]]&lt;br /&gt;
* [[Minimizing a structure using OPTIM and CHARMM]]&lt;br /&gt;
* [[Creating movies (.mpg) of paths using OPTIM]]&lt;br /&gt;
* [[Performing a normal mode analysis of a biomolecule using OPTIM (AMBER and CHARMM)]]&lt;br /&gt;
* [[Debugging odd transition states in OPTIM]]&lt;br /&gt;
* [[Connecting two minima with a pathway]] - step by step&lt;br /&gt;
* [[Compiling and using OPTIM with QUIP]]&lt;br /&gt;
* [[Running an Gaussian03 interfaced OPTIM job]]&lt;br /&gt;
* [[The effect of calculating less than the maximum number of eigenvalues using ENDHESS n]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[BLJ60 example setup]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Python interface for GMIN/OPTIM]]&lt;br /&gt;
* [[Thomson problem in OPTIM]]&lt;br /&gt;
* [[Instanton tunneling and classical rate calculations with OPTIM]]&lt;br /&gt;
* [[Loading OPTIM&#039;s min.data.info files into PATHSAMPLE]]&lt;br /&gt;
* [[common setup problem : No Frequency Warning]]&lt;br /&gt;
&lt;br /&gt;
=== [[PATHSAMPLE]] ===&lt;br /&gt;
* [[Adding a model to PATHSAMPLE]] - rough outline of the subrounties that need to be changed to add a new model to PATHSAMPLE&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself]]&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself (CHARMM)]]&lt;br /&gt;
* [[perm-pdb.py]]: A python program that creates a &#039;&#039;perm.allow&#039;&#039; file for use with [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
* [[dijkstra_test.py]]: A python script to test whether the information in pairlist and ts.data connects the A and B set. (If not, PATHSAMPLE will not work without actually exiting.)&lt;br /&gt;
* [[Compiling Wales Group codes using cmake | Compiling PATHSAMPLE using cmake ]]&lt;br /&gt;
* [[IMPORTANT: Using PATHSAMPLE safely on sinister]]&lt;br /&gt;
* [[Adding a model for PATHSAMPLE]]&lt;br /&gt;
* [[List of output files for PATHSAMPLE]]&lt;br /&gt;
* [[Using BHINTERP to find minima between two end points]]&lt;br /&gt;
* [[Finding an initial path between two end points (minima)]]&lt;br /&gt;
* [[Adding partially finished OPTIM stationary points to a PATHSAMPLE database]]&lt;br /&gt;
* [[Optimising a path]]&lt;br /&gt;
* [[Fine tuning UNTRAP]] - ensuring that it picks sensible minima&lt;br /&gt;
* [[Calculating rate constants (GT and fastest path)]]&lt;br /&gt;
* [[Calculating rate constants (SGT, DGT, and SDGT)]]&lt;br /&gt;
* [[Identifying the k fastest paths between endpoints using KSHORTESTPATHS]]&lt;br /&gt;
* [[Removing minima and transition states from the database]]&lt;br /&gt;
* [[Relaxing existing minima with new potential and creating new database]]&lt;br /&gt;
* [[Relaxing existing transition states with new potential and creating new database]]&lt;br /&gt;
* [[If things go wrong...]]&lt;br /&gt;
* [[If you lost file min.data, but still you have points.min]]&lt;br /&gt;
* [[path.info file is not read, causes PATHSAMPLE to die]]&lt;br /&gt;
* [[BLJ60 example setup]]&lt;br /&gt;
* [[When PATHSAMPLE finds a connected path, but using DIJKSTRA 0 fails to find the connected path]]&lt;br /&gt;
* [[Biomolecules in PATHSAMPLE]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[Expanding the kinetic transition network with PATHSAMPLE]]&lt;br /&gt;
* [[Expanding the kinetic transition network with PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Pathsampling short paths]]&lt;br /&gt;
* [[Pathsampling short paths (CHARMM)]]&lt;br /&gt;
* [[Loading OPTIM&#039;s min.data.info files into PATHSAMPLE]]&lt;br /&gt;
* [[Connecting Sub-databases]]&lt;br /&gt;
* [[CHECKSPMUTATE]]: An extension of CHECKSPODATA which allows for a protein to be mutated or transformed into a homologue.&lt;br /&gt;
* [[Pathway Gap Filling Post-CHECKSPMUTATE]]: Post-processing following CHECKSPMUTATE&lt;br /&gt;
* [[STARTING INITIAL PATH JOBS WITH PATHSAMPLE]]: How to start initial path jobs with PATHSAMPLE if no min.data or path.info files are present.&lt;br /&gt;
&lt;br /&gt;
=== [[Notes on MINPERMDIST | MINPERMDIST]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Quasi-continuous interpolation for biomolecules | QCI]] ===&lt;br /&gt;
&lt;br /&gt;
== Non-Group Software ==&lt;br /&gt;
&lt;br /&gt;
=== [[AMBER]] ===&lt;br /&gt;
Molecular dynamics simulation program and associated force fields.&lt;br /&gt;
* [http://ambermd.org/ AMBER]&lt;br /&gt;
* [http://ambermd.org/tutorials/ AMBER tutorials] - recommended reading for &#039;&#039;&#039;ANYONE&#039;&#039;&#039; using AMBER!&lt;br /&gt;
* [[Notes on AMBER 12 interface]]&lt;br /&gt;
* [[Using AMBER 14 on the GPU and compute clusters]]&lt;br /&gt;
* [[Generating parameters using AMBER&#039;s built in General Forcefield (gaff)]]&lt;br /&gt;
* [[Generating parameters using RESP charges from GAMESS-US]]&lt;br /&gt;
* [[Simple scripts for LEaP to create topology and coordinate files]] &lt;br /&gt;
* [[Preparing an AMBER topology file for a protein system]] - step by step guide&lt;br /&gt;
* [[Setting up]] - step by step guide to prepare and then symmetrise a simple (protein-only) system&lt;br /&gt;
* [[Using Molfacture to edit molecules and add hydrogens]]&lt;br /&gt;
* [[Preparing an AMBER topology file for a protein plus ligand system]] - step by step guide&lt;br /&gt;
* [[Symmetrising AMBER topology files]] - step by step guide for symmetrising a complex protein+ligand system&lt;br /&gt;
* [[Producing a PDB from a coordinates and topology file]] - using &#039;&#039;amdpdb&#039;&#039;&lt;br /&gt;
* [[Running GMIN with MD move steps AMBER]]&lt;br /&gt;
* [[Performing a normal mode analysis of a biomolecule using OPTIM (AMBER and CHARMM)]]&lt;br /&gt;
* [[Evaluating different components of AMBER energy function with SANDER]]&lt;br /&gt;
* [[Mutational BH steps]]&lt;br /&gt;
* [[CHECKSPMUTATE]]: An extension of CHECKSPODATA which allows for a protein to be mutated or transformed into a homologue.&lt;br /&gt;
* [[Pathway Gap Filling Post-CHECKSPMUTATE]]: Post-processing following CHECKSPMUTATE&lt;br /&gt;
* [[REMD with AMBER]]&lt;br /&gt;
* [[Performing a hydrogen-bond analysis]]&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[perm-prmtop.py]] - A python program that converts an AMBER9 topology file into one with a symmetrised potential with respect to exchange (updated for AMBER12 and ff14SB).&lt;br /&gt;
* [[Rotamer moves in AMBER]]&lt;br /&gt;
* [[Creating mismatched DNA duplex using NAB]]&lt;br /&gt;
&lt;br /&gt;
=== [[aux2bib]] === &lt;br /&gt;
To generate a bib file containing only the entries cited in a given .tex file from a larger bib or multiple bib files.&lt;br /&gt;
* [https://ctan.org/pkg/bibtools Get script here]&lt;br /&gt;
&lt;br /&gt;
=== [[CamCasp]] ===&lt;br /&gt;
Cambridge package for Calculation of Anisotropic Site Properties&lt;br /&gt;
From Anthony Stone&#039;s website: &#039;CamCASP is a collection of scripts and programs written by Dr Alston Misquitta and myself for the calculation ab initio of distributed multipoles, polarizabilities, dispersion coefficients and repulsion parameters for individual molecules, and interaction energies between pairs of molecules using SAPT(DFT).&#039;&lt;br /&gt;
* [http://www-stone.ch.cam.ac.uk/programs.html CamCASP home]&lt;br /&gt;
* [[CamCASP/Programming]]&lt;br /&gt;
* [[CamCASP/Programming/5/example1]]&lt;br /&gt;
* [[CamCASP/Notes]]&lt;br /&gt;
* [[CamCASP/Bugs]]&lt;br /&gt;
* [[CamCASP/ToDo/diskIO]]&lt;br /&gt;
* [[CamCASP/ToDo/Memory]]&lt;br /&gt;
* [[CamCASP/CodeExamples/DirectAccess]]&lt;br /&gt;
&lt;br /&gt;
=== [[CPMD]] ===&lt;br /&gt;
Implementation of DFT for &#039;&#039;ab-initio&#039;&#039; molecular dynamics.&lt;br /&gt;
* [http://www.cpmd.org/ Home Page]&lt;br /&gt;
* [[CPMDInput]]&lt;br /&gt;
&lt;br /&gt;
=== [[CHARMM]] ===&lt;br /&gt;
Molecular dynamics simulation program and associated force fields.&lt;br /&gt;
* [https://www.charmm.org/charmm/?CFID=65f7b3aa-8037-452a-bcd1-7583dd83a087&amp;amp;CFTOKEN=0 CHARMM]&lt;br /&gt;
* [[Generating pdb, crd and psf for a peptide sequence]]&lt;br /&gt;
* [[Converting between &#039;.crd&#039; and &#039;.pdb&#039;]]&lt;br /&gt;
* [[Calculating energy of a conformation]]&lt;br /&gt;
* [[Calculating molecular properties]]&lt;br /&gt;
* [[Calculating order parameters]]&lt;br /&gt;
* [[CAMSHIFT]]&lt;br /&gt;
* [[Setting up (CHARMM)]] - step by step guide to prepare and then symmetrise a simple (protein-only) system&lt;br /&gt;
* [[If you need to change the number of atoms (e.g. making a united-atom charmm19 .crd file, or if atoms are missing)]]&lt;br /&gt;
* [[Performing a normal mode analysis of a biomolecule using OPTIM (AMBER and CHARMM)]]&lt;br /&gt;
* [[Minimizing a structure using OPTIM and CHARMM]]&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself (CHARMM)]]&lt;br /&gt;
* [[Expanding the kinetic transition network with PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Pathsampling short paths (CHARMM)]]&lt;br /&gt;
&lt;br /&gt;
=== [[disconnectionDPS]] ===&lt;br /&gt;
Produces disconnectivity graphs from min.data and ts.data files. This is included in the Wales group public tarball.&lt;br /&gt;
* [[Constructing Free Energy Disconnectivity Graphs]]&lt;br /&gt;
&lt;br /&gt;
=== [[DMACRYS]] ===&lt;br /&gt;
Package which models crystals of rigid molecules.&lt;br /&gt;
* [http://www.chem.ucl.ac.uk/cposs/dmacrys/index.html Home Page]&lt;br /&gt;
* [[DMACRYS interface]]&lt;br /&gt;
* [[DMAGMIN setup]]&lt;br /&gt;
* [[PYGMIN &amp;amp; DMACRYS]]&lt;br /&gt;
&lt;br /&gt;
=== [[GAMESS]] ===&lt;br /&gt;
General &#039;&#039;ab initio&#039;&#039; quantum chemistry package.&lt;br /&gt;
* [https://www.msg.chem.iastate.edu/gamess/ GAMESS]&lt;br /&gt;
&lt;br /&gt;
=== [[Gaussian]] ===&lt;br /&gt;
General purpose package for computational chemistry calculations.&lt;br /&gt;
* [[Running an Gaussian03 interfaced OPTIM job]]&lt;br /&gt;
&lt;br /&gt;
=== [[gnuplot]] ===&lt;br /&gt;
Open source graphing program.&lt;br /&gt;
* [http://www.gnuplot.info/ gnuplot]&lt;br /&gt;
* [[Plotting a quick histogram in gnuplot using the raw data]]&lt;br /&gt;
* [[Plotting data in real time]]&lt;br /&gt;
* [[Linear and non-linear regression in gnuplot]]&lt;br /&gt;
&lt;br /&gt;
=== [[GROMACS]] ===&lt;br /&gt;
Molecular dynamics package.&lt;br /&gt;
* [[Installing GROMACS on Clust]]&lt;br /&gt;
* [http://www.mdtutorials.com/gmx/ External tutorials]&lt;br /&gt;
* [http://www.gromacs.org/Documentation/Tutorials More external tutorials]&lt;br /&gt;
&lt;br /&gt;
=== [[HiRE-RNA]] ===&lt;br /&gt;
High-res course-grained energy model for RNA.&lt;br /&gt;
* [https://pubs.acs.org/doi/10.1021/jp102497y Explanatory Paper]&lt;br /&gt;
&lt;br /&gt;
=== [[latex2html]] ===&lt;br /&gt;
Script which converts latex documents into HTML pages.&lt;br /&gt;
* [https://www.latex2html.org/ Get script here]&lt;br /&gt;
&lt;br /&gt;
=== [[MMTSB-toolset]] ===&lt;br /&gt;
Group of perl scripts which can be used to setup and run energy minimization, structural analysis and MD with CHARMM or AMBER.&lt;br /&gt;
* [http://feig.bch.msu.edu/mmtsb/Main_Page Documentation]&lt;br /&gt;
* [http://www.mmtsb.org/workshops/mmtsb-ctbp_2006/Tutorials/WorkshopTutorials_2006.html External tutorials]&lt;br /&gt;
* [[Installing and setting up the MMTSB toolset]]&lt;br /&gt;
* [[REX (Replica EXchange MD) with the MMTSB-toolset]]&lt;br /&gt;
&lt;br /&gt;
=== [[Simulations using OPEP | OPEP]] ===&lt;br /&gt;
OPEP is a coarse-grained force field providing a potential for proteins and RNA.&lt;br /&gt;
* [http://opep.galaxy.ibpc.fr/ OPEP file generator here]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
&lt;br /&gt;
=== [[pgprof]] === &lt;br /&gt;
Profiler for portland-compiled codes&lt;br /&gt;
* [[Portland compiler fails trying to allocate an unexpectedly large amount of memory: issue with large arrays]]&lt;br /&gt;
&lt;br /&gt;
=== [[Pymol]] ===&lt;br /&gt;
Molecular visualisation program.&lt;br /&gt;
* [https://pymol.org/2/ PyMOL]&lt;br /&gt;
* [https://pymolwiki.org/index.php/Main_Page PyMOL Community Wiki]&lt;br /&gt;
* [[loading AMBER prmtop and inpcrd files into Pymol]]&lt;br /&gt;
* [[producing sexy ray-traced images]]&lt;br /&gt;
* [[advanced colouring]]&lt;br /&gt;
* [[Installing python modules]]&lt;br /&gt;
* [[PYGMIN &amp;amp; DMACRYS]]&lt;br /&gt;
* [[path2pdb.py]] - A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.pdb&#039;&#039; - you can easy visualize your path in VMD :)&lt;br /&gt;
* [[extractedmin2pdb.py]]: A python program to convert &#039;&#039;exctractedmin&#039;&#039; to PDB format&lt;br /&gt;
=== [[VASP]] ===&lt;br /&gt;
OPTIM has an interface to VASP, which is installed on CSD3. In collaboration with Bora Karasulu the interface has been updated to use VASP format POSCAR input files for both single- and double-ended optimisations and path searches. The OPTIM odata file requires a line like&lt;br /&gt;
&lt;br /&gt;
VASP &#039;mpirun -ppn 16 -np 16 /home/bk393/APPS/vasp.5.4.4/with-VTST/bin/vasp_std &amp;gt; vasp.out&#039;&lt;br /&gt;
&lt;br /&gt;
POSCAR files can be visualised using ase, the Atomic Simulation Environment, which can be accessed on volkhan via&lt;br /&gt;
&lt;br /&gt;
module load anaconda/python3/5.3.0 &lt;br /&gt;
&lt;br /&gt;
pip install ase --user&lt;br /&gt;
&lt;br /&gt;
ase-gui POSCAR1.vasp &amp;amp;&lt;br /&gt;
&lt;br /&gt;
which assumes that ~/.input/bin is in your $PATH environment variable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [[VMD]] ===&lt;br /&gt;
Molecular visualisation program.&lt;br /&gt;
* [http://www.ks.uiuc.edu/Research/vmd/current/ug/ug.html Documentation]&lt;br /&gt;
* [http://www.ks.uiuc.edu/Training/Tutorials/vmd/tutorial-html/index.html External tutorials]&lt;br /&gt;
* [[using VMD to display and manipulate &#039;.pdb&#039; files]]&lt;br /&gt;
* [[loading coordinate files into VMD with the help of an AMBER topology file]] e.g. to visualise the results of a GMIN run using AMBER9&lt;br /&gt;
* [[visualising normal modes using VMD and OPTIM]]&lt;br /&gt;
* [[path2pdb.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.pdb&#039;&#039; - you can easy visualize your path in VMD :)&lt;br /&gt;
* [[path2xyz.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.xyz&#039;&#039;&lt;br /&gt;
* [[extractedmin2pdb.py]]: A python program to convert &#039;&#039;exctractedmin&#039;&#039; to PDB format&lt;br /&gt;
* [[Useful .vmdrc file]]&lt;br /&gt;
* [[plotGMINms.tcl]]: a tcl script for plotting ellipsoids in VMD.&lt;br /&gt;
* [[VMD script to annotate each frame of a trajectory]]&lt;br /&gt;
&lt;br /&gt;
=== [[xfig]] ===&lt;br /&gt;
Open source vector graphics editor&lt;br /&gt;
* [https://ctan.org/tex-archive/support/epstopdf/ Convert eps to pdf]&lt;br /&gt;
&lt;br /&gt;
=== [[Xmakemol]] ===&lt;br /&gt;
Program for visualising atomic and molecular systems.&lt;br /&gt;
* [https://www.nongnu.org/xmakemol/ XMakemol]&lt;br /&gt;
&lt;br /&gt;
=== [[xmgrace]] ===&lt;br /&gt;
2D plotting tool.&lt;br /&gt;
* [http://exciting-code.org/xmgrace-quickstart Xmgrace]&lt;br /&gt;
&lt;br /&gt;
== Theoretical/Mathematical Notes ==&lt;br /&gt;
&lt;br /&gt;
* [[Density of states and thermodynamics from energy distributions at different temperatures]]&lt;br /&gt;
* [[Ellipsoid.model]]&lt;br /&gt;
* [[Ellipsoid.model.xyz]]&lt;br /&gt;
* [[Ellipsoid.xyz]]&lt;br /&gt;
* [[Gencoords]]&lt;br /&gt;
* [[GenCoords]]&lt;br /&gt;
* [[GenCoords Models]]&lt;br /&gt;
* [[Rotamer moves in AMBER]]&lt;br /&gt;
* [[Thomson problem in OPTIM]]&lt;br /&gt;
&lt;br /&gt;
=== Angle-axis notes ===&lt;br /&gt;
&lt;br /&gt;
* [[Angle-axis framework]]&lt;br /&gt;
* [[Computing normal modes in angle-axis]]&lt;br /&gt;
&lt;br /&gt;
=== Rigid Bodies ===&lt;br /&gt;
&lt;br /&gt;
* [[Automatic Rigid Body Grouping]]&lt;br /&gt;
* [[Rigid body input files for proteins using genrigid-input.py]]&lt;br /&gt;
* [[Local Rigid Body Framework]]&lt;br /&gt;
* [[Local rigid body in OPTIM]]&lt;br /&gt;
&lt;br /&gt;
== Useful Scripts ==&lt;br /&gt;
* [[perm-prmtop.py]]: A python program that converts an AMBER9 topology file into one with a symmetrised potential with respect to exchange (updated for AMBER12 and ff14SB).&lt;br /&gt;
* [[perm-pdb.py]]: A python program that creates a &#039;&#039;perm.allow&#039;&#039; file for use with [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
* [[path2pdb.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.pdb&#039;&#039; - you can easy visualize your path in VMD :)&lt;br /&gt;
* [[path2xyz.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.xyz&#039;&#039;&lt;br /&gt;
* [[dijkstra_test.py]]: A python script to test whether the information in pairlist and ts.data connects the A and B set. (If not, PATHSAMPLE will not work without actually exiting.)&lt;br /&gt;
* [[extractedmin2pdb.py]]: A python program to convert &#039;&#039;exctractedmin&#039;&#039; to PDB format&lt;br /&gt;
* [[colourdiscon.py]]: A python program for sorting input for disconnectivity graphs&lt;br /&gt;
* [[pdb_to_movie.py]]: A python program to create an AMH movieseg file from a PDB file&lt;br /&gt;
* [[makerestart]]: A bash script to automatically set up a GMIN restart run&lt;br /&gt;
* [[progress]] A bash script to tell you the % completion of a GMIN job and give an estimated time remaining&lt;br /&gt;
* [[recommended bash aliases]]&lt;br /&gt;
* [[David&#039;s .inputrc file]]&lt;br /&gt;
* [[Useful .vmdrc file]]&lt;br /&gt;
* [[Density of states and thermodynamics from energy distributions at different temperatures]]&lt;br /&gt;
* [[GenCoords]]: A fortran program to generate coarse grain building blocks and initial coords using a set of geometric models.&lt;br /&gt;
* [[plotGMINms.tcl]]: a tcl script for plotting ellipsoids in VMD.&lt;br /&gt;
See also the SCRIPTS/ directory in the SVN repository!&lt;br /&gt;
* [[Computing CHARMM FF energy using GMIN, MMTSB and CHARMM]] - Computes the Charmm FF energy of the same structure. Useful for cross-validating force field settings in GMIN data file, CHARMM input file and MMTSB options.&lt;br /&gt;
* [[Automatic Rigid Body Grouping]]&lt;br /&gt;
* [[ElaborateDiff]]&lt;br /&gt;
* [[Parameter-scanning script]]&lt;br /&gt;
* [[Pdb to movie.py]]&lt;br /&gt;
* [[VMD script to annotate each frame of a trajectory]]&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [http://www.ch.cam.ac.uk/computing/theory-compute-clusters The Theory Compute Clusters support page]. Contains useful cluster specific information, including example job submission scripts.&lt;br /&gt;
&lt;br /&gt;
* A useful website which contains AMBER (GAFF) and OPLS parameters for small molecules. http://virtualchemistry.org/gmld.php . This could save us lot of time while trying to derive parameters on our own. If you are lucky, the molecule of your interest may already be there in the existing database. The topology files are in GROMACS format but possibly can be converted into AMBER parameter files. (script anyone ?)&lt;br /&gt;
&lt;br /&gt;
* The moving-domain QM/MM method developed by Victor Batista&#039;s group http://gascon.chem.uconn.edu/software. This approach can be used in the derivation of charges for large proteins and nucleic acids, where a full-fledged ONIOM based calculation is comptutationally prohibitive. It has been applied to systems like the Gramicidin ion channel and Photosystem II.&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
* [[Animated GIF on the group website]]&lt;br /&gt;
* [[Backup strategy]]&lt;br /&gt;
* [[Chain crossing]]&lt;br /&gt;
* [[Computer Office services]]&lt;br /&gt;
* [[Computing values only once]]&lt;br /&gt;
* [[Decoding heat capacity curves]]&lt;br /&gt;
* [[Differences from Clust]]&lt;br /&gt;
* [[Fixing thunderbird links]]&lt;br /&gt;
* [[If you need to change the number of atoms (e.g. making a united-atom charmm19 .crd file, or if atoms are missing)]]&lt;br /&gt;
* [[Intel Trace Analyzer and Collector]]&lt;br /&gt;
* [[LDAP plans]]&lt;br /&gt;
* [[Lapack compilation]]&lt;br /&gt;
* [[Mek-quake Queueing system]]&lt;br /&gt;
* [[Mek-quake initial setup notes]]&lt;br /&gt;
* [[New mek-quake]]&lt;br /&gt;
* [[Maui compilation]]&lt;br /&gt;
* [[Torque and Maui]]&lt;br /&gt;
* [[Mercurial]]&lt;br /&gt;
* [[Migrating to the new SVN server]]&lt;br /&gt;
* [[NECI Parallelization]]&lt;br /&gt;
* [[Optimization tricks]]&lt;br /&gt;
* [[Other IT stuff]]&lt;br /&gt;
* [[Porfuncs Documentation]]&lt;br /&gt;
* [[Progress]]&lt;br /&gt;
* [[Proposed changes to backup and archiving]]&lt;br /&gt;
* [[Rama upgrade]]&lt;br /&gt;
* [[Remastering Knoppix]]&lt;br /&gt;
* [[See unpacked nodes]]&lt;br /&gt;
* [[Tardis scheduling policy]]&lt;br /&gt;
* [[Zippo Sicortex machine]]&lt;br /&gt;
* [[Beginner&#039;s guide to working in Wales group]]&lt;br /&gt;
&lt;br /&gt;
== Useful linux stuff ==&lt;br /&gt;
&lt;br /&gt;
===Basics===&lt;br /&gt;
* [[basic linux commands everyone should know!]]&lt;br /&gt;
* [[piping and redirecting output from one command or file to another]] - how to save yourself hours!&lt;br /&gt;
* [[bash loop tricks]]&lt;br /&gt;
* [[bash history searching]]&lt;br /&gt;
&lt;br /&gt;
===Remote access===&lt;br /&gt;
* [[setting up aliases to quickly log you in to a different machine]]&lt;br /&gt;
* [[transfering files to and from your workstation]] -using &#039;&#039;scp&#039;&#039; or &#039;&#039;rsync&#039;&#039;&lt;br /&gt;
* [[using &#039;ssh-keygen&#039; to automatically log you into clusters from your workstation]] (no more typing in your password!)&lt;br /&gt;
* [[mounting sharedscratch locally]]&lt;br /&gt;
&lt;br /&gt;
===Find and replace===&lt;br /&gt;
* [[short &#039;sed&#039; examples]]&lt;br /&gt;
* [[quick guide to awk]]&lt;br /&gt;
* [[short &#039;awk&#039; examples]]&lt;br /&gt;
&lt;br /&gt;
===File manipulation===&lt;br /&gt;
* [[sorting a file by multiple columns]]&lt;br /&gt;
* [[using tar and gzip to compress/uncompress files | using tar and bzip2 to compress/uncompress files]]&lt;br /&gt;
* [[conversion between different data file formats]] -&#039;almost one-line&#039; scripts&lt;br /&gt;
* [[conversion between different image file formats]] - the &#039;&#039;convert&#039;&#039; command&lt;br /&gt;
* [[removing an excessive number of files from a directory - when &#039;rm&#039; just isn&#039;t enough]]&lt;br /&gt;
&lt;br /&gt;
===Cluster queues===&lt;br /&gt;
* [[submitting jobs, interactively or to a cluster queue system]]&lt;br /&gt;
* [[identifying job on a node]] - if you need to kill only one of few running jobs&lt;br /&gt;
* [[getting started with SLURM]]&lt;br /&gt;
* [[a guide to using SLURM to run PATHSAMPLE]]&lt;br /&gt;
* [[a guide to using SLURM to run GPU jobs on pat]]&lt;br /&gt;
* [[managing interactive jobs on cluster]]&lt;br /&gt;
&lt;br /&gt;
===Miscellaneous/uncategorised===&lt;br /&gt;
* [[installing packages on your managed CUC3 workstation]]&lt;br /&gt;
* [[running programs in the background]] - so you can use your shell for other things at the same time&lt;br /&gt;
* [[finding bugs in latex documents that will not compile]]&lt;br /&gt;
* [[printing files from the command line using &#039;lpr&#039;]]&lt;br /&gt;
* [[uploading non image files to the wiki]]&lt;br /&gt;
&lt;br /&gt;
== Compiler Flags ==&lt;br /&gt;
&lt;br /&gt;
* [[Compiler Flags]]&lt;br /&gt;
* [[Blacklisting Compilers]]&lt;br /&gt;
* [[Lapack compilation]]&lt;br /&gt;
* [[Pdb to movie.py]]&lt;br /&gt;
* [[Portland compiler fails trying to allocate an unexpectedly large amount of memory: issue with large arrays]]&lt;br /&gt;
&lt;br /&gt;
== SuSE ==&lt;br /&gt;
&lt;br /&gt;
* [[Upgrading destiny]]&lt;br /&gt;
* [[Upgrading sword]]&lt;br /&gt;
* [[SuSE 10.1 workstation image]]&lt;br /&gt;
* [[SuSE 10.2 workstation image]]&lt;br /&gt;
* [[SuSE 10.3 workstation image]]&lt;br /&gt;
* [[SuSE 11.1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:adk44|adk44]] 17.00, 9 May 2019 (BST)&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1725</id>
		<title>Git Workflow</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Git_Workflow&amp;diff=1725"/>
		<updated>2020-09-28T10:09:24Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Moved from private wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Group software and papers in the process of being written are stored on the University&#039;s GitLab repositories [https://gitlab.developers.cam.ac.uk/]. You should be able to log in via Raven, but someone with privileges will need to add you to the two projects. This page describes a typical workflow for retrieving, modifying and updating the repositories. It is not, however, a comprehensive guide to Git. For that, consult your favourite web search engine.&lt;br /&gt;
&lt;br /&gt;
==Setting up SSH access==&lt;br /&gt;
&lt;br /&gt;
To smoothly access Gitlab without having to type your user name and password the whole time, set up an SSH key. In a terminal on your desktop, type&lt;br /&gt;
&lt;br /&gt;
  $ ssh-keygen -t ed25519 -C &amp;quot;GitLab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If it complains about overwriting, then you have already done this step and you probably don&#039;t want to overwrite. It will ask you where to save the key: the default location should be fine. Now you are prompted for a passphrase. You can press ENTER to leave it blank, although that does mean that anyone who breaks into your computer can get access to GitLab with no further effort. You now have a file (defualt location is ~/.ssh/id_ed25519.pub) that contains your public key. Copy the entire contents of this file. &lt;br /&gt;
&lt;br /&gt;
On the GitLab website, click on your user icon in the top right and select &#039;Settings&#039; and then &#039;SSH Keys&#039; from the left menu. Paste the contents of your public key file into the box. Put something useful in the title, like the name of your desktop (yes, you should probably do this for each machine you want to access GitLab from, rather than copying keys between machines). Optionally, you can insert an expiry date, such as the date your funding runs out. Click the &#039;Add key&#039; button.&lt;br /&gt;
&lt;br /&gt;
To test that you now have access, in a terminal type&lt;br /&gt;
&lt;br /&gt;
  $ ssh -T git@gitlab.developers.cam.ac.uk&lt;br /&gt;
&lt;br /&gt;
After accepting the RSA identity, you should see a welcome message and then the connection will close.&lt;br /&gt;
&lt;br /&gt;
==Initial Checkout==&lt;br /&gt;
&lt;br /&gt;
You need to fetch the repository. In Git terms, this is called cloning. You should only need to carry out this step once for each repository. In your favourite web browser, navigate to the project page on Gitlab [https://gitlab.developers.cam.ac.uk/ch/wales/paperswales papers]. Spot the blue button on the right labelled &#039;Clone&#039; and click on it. Copy the link under &#039;Clone with SSH&#039; to the clipboard. In a terminal, choose a suitable location, like your home directory and change to there. Now type&lt;br /&gt;
&lt;br /&gt;
  $ git clone git@gitlab.developers.cam.ac.uk:ch/wales/paperswales.git&lt;br /&gt;
&lt;br /&gt;
replacing, the address with what you just copied. Git will download the repository. Once it has finished, check that you now have lots of new directories with the contents of the repository.&lt;br /&gt;
&lt;br /&gt;
==Basic Workflow==&lt;br /&gt;
&lt;br /&gt;
Details for specific cases are below, but first, we mention the most important commands that you&#039;ll be running all the time. Imagine you&#039;ve just arrived in the morning and it&#039;s time to start working on  myfile.f90. The first command to run is&lt;br /&gt;
&lt;br /&gt;
  $ git pull&lt;br /&gt;
&lt;br /&gt;
This command contacts the remote repository on GitLab and fetches any commits that people may have made. Run this command frequently, and at least before every commit you make. Now you edit myfile.90 and want to commit your changes. Run&lt;br /&gt;
&lt;br /&gt;
  $ git add myfile.f90&lt;br /&gt;
&lt;br /&gt;
Now the file is, in Git terminology, staged for commit. You haven&#039;t committed anything yet. You can add other files to the staging area too. Once your commit is ready, run&lt;br /&gt;
&lt;br /&gt;
  $ git commit -m &amp;quot;Informative message.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Replace &#039;Informative message&#039; with a brief message describing what changes are in your commit. At this point, you have updated your local repository and entered a commit in the permanent record. However, the commit hasn&#039;t gone to GitLab yet. To send it to GitLab (called the remote by Git), run&lt;br /&gt;
&lt;br /&gt;
  $ git push&lt;br /&gt;
&lt;br /&gt;
You can send multiple commits at once. This workflow should encourage you to commit often. Maybe you write a new function. Put in a commit. Then you add some stuff to keywords.f90 for the new functionality. Do another commit. Next you find a bug and fix it. Do another commit.&lt;br /&gt;
&lt;br /&gt;
Note that the remote can function as the backup of your work. Therefore you should probably push any new commits at least as often as the end of each day.&lt;br /&gt;
&lt;br /&gt;
==Writing a Paper==&lt;br /&gt;
&lt;br /&gt;
Writing a paper is slightly simpler than editing the group code (Discuss...) because we aren&#039;t worrying about multiple branches. Create a new directory for your paper and use git add to add it. Start writing the paper in the new directory. Each session of editing should involve&lt;br /&gt;
&lt;br /&gt;
# git pull&lt;br /&gt;
# make some edits&lt;br /&gt;
# git pull&lt;br /&gt;
# git add all the edited files&lt;br /&gt;
# git commit with a helpful message&lt;br /&gt;
# git push&lt;br /&gt;
&lt;br /&gt;
Simples. All authors will be editing the same branch (the master branch), so you&#039;ll see other authors&#039; updates straight away. This approach keeps things easy, but if two authors are working at exactly the same time, there may be some merging to do. Reduce the amount of merging by pulling and pushing often.&lt;br /&gt;
&lt;br /&gt;
==Working on the group code==&lt;br /&gt;
&lt;br /&gt;
You&#039;ve just been talking to David and you&#039;ve come up with an exciting new feature to add to GMIN. It&#039;s going to take several days of coding, during which you&#039;ll want to back up your work on the remote, but you don&#039;t want to interfere with other people using GMIN. The solution is to create a new branch. A branch is your own version controlled copy of the code that you can edit at will without messing GMIN up for anyone else. All development should occur on branches. To create a new branch, run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -b exciting_feature&lt;br /&gt;
&lt;br /&gt;
This command both creates the branch and switches your working copy to it. Initially, your new branch is the same as the master branch you cut it from. However, the branch does not yet exist on GitLab. To create it, run&lt;br /&gt;
&lt;br /&gt;
  $ git push --set-upstream origin exciting_feature&lt;br /&gt;
&lt;br /&gt;
Now go ahead and edit files, making commits and pushing them to GitLab frequently.&lt;br /&gt;
&lt;br /&gt;
When your feature is complete and you have checked it works and that you haven&#039;t broken anything else, it&#039;s time to get it into the master branch. Several steps are required. Firstly, it&#039;s quite likely that other people have changed master since you cut off your branch. You don&#039;t want your commit to undo those changes, so you need to bring your branch up to date with master. Run&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git checkout exciting_feature&lt;br /&gt;
  $ git rebase master&lt;br /&gt;
&lt;br /&gt;
The pull commands makes sure that your local copy of the repository is up to date. The rebase command applies any changes that have been made to the master branch to your branch. It rewrites the history so it looks like your branch was cut from the most recent master commit. Now check again that your new feature works.&lt;br /&gt;
&lt;br /&gt;
Most users do not have permission to edit the master branch. To get your new feature in, you have to create a merge request. Go to the project page on GitLab. From the drop down menu of branches, select exciting_feature. Click the blue &#039;Create merge request&#039; button in the top right. You now have a page in which you can give your merge request a title and description. You can also choose who to assign it to. That person will get a notification and a copy of your changes. They will look through your changes to make sure they follow the group coding standards ([[Wales Group Fortran conventions for group software |here]]) and that you haven&#039;t broken anything. If there are any issues, they may request that you make some changes, which you can then commit to the exciting_feature branch. The pull request will be updated and the reviewer will get a notification. Once your code has passed the review, the reviewer will click the button and your branch will be merged into master. If you selected the checkbox to delete feature branch on merge, your branch will be deleted once the commits have been merged into master. Otherwise, you can clean up your repository with the following commands&lt;br /&gt;
&lt;br /&gt;
  $ git checkout master&lt;br /&gt;
  $ git pull&lt;br /&gt;
  $ git branch -d exciting_feature&lt;br /&gt;
&lt;br /&gt;
These commands switch your working copy back to master, update your local copy of the repository, and delete the branch you made.&lt;br /&gt;
&lt;br /&gt;
==Useful commands to know==&lt;br /&gt;
&lt;br /&gt;
  $ git status&lt;br /&gt;
&lt;br /&gt;
At any point, this command will show you what branch you are on, what files you have modified and staged and your local position compared to the remote. Use it often.&lt;br /&gt;
&lt;br /&gt;
  $ git branch&lt;br /&gt;
&lt;br /&gt;
Display a list of all the current branches.&lt;br /&gt;
&lt;br /&gt;
  $ git diff&lt;br /&gt;
&lt;br /&gt;
Show the differences between your working copy and the last commit, for all files. Add a file name to show only the differences for a specific file.&lt;br /&gt;
&lt;br /&gt;
  $ git log&lt;br /&gt;
&lt;br /&gt;
Display the commit history. Add a file or directory name afterwards to only show the commits that affected that file, or any file in the directory.&lt;br /&gt;
&lt;br /&gt;
  $ git reset HEAD myfile.f90&lt;br /&gt;
&lt;br /&gt;
Unstage myfile.f90 that you accidentally staged for the next commit, but actually don&#039;t want to commit just yet. The working copy of the file is not altered.&lt;br /&gt;
&lt;br /&gt;
  $ git checkout -- myfile.f90&lt;br /&gt;
&lt;br /&gt;
Revert myfile.f90 that you&#039;ve completely messed up to what it was at the last commit. Changes to your working copy are lost.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to the last commit.&lt;br /&gt;
&lt;br /&gt;
  $ git reset --hard 909a3cac63ae8782b258ebb8c27af361b555bff6&lt;br /&gt;
&lt;br /&gt;
Throw away all working and staged changes, reverting the current state to that of the commit specified. The long hex number is a commit hash. It is not human readable, but you can copy the relevant one from the commit log.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Getting_started_with_SLURM&amp;diff=1602</id>
		<title>Getting started with SLURM</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Getting_started_with_SLURM&amp;diff=1602"/>
		<updated>2020-05-27T13:58:43Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Theory */ Fixed some typos.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For running computationally expensive tasks for long periods of time, you will want to create a job and run it on a cluster. This page is intended to teach you everything required to run your first job on a SLURM CPU cluster (sinister, volkhan). For convenience, we will refer primarily to sinister, but the information is transferrable to other SLURM clusters, with a small note about SLURM versions [[A guide to using SLURM to run PATHSAMPLE | here]]. This page does not contain information about PBS (dexter), but there is some information [[Submitting jobs, interactively or to a cluster queue system | here]]. If you are running GPU (pat) jobs, you will need additional information from [[A guide to using SLURM to run GPU jobs on pat | here]].&lt;br /&gt;
&lt;br /&gt;
==Basic terminology==&lt;br /&gt;
&lt;br /&gt;
A cluster is a large computer that has many processors. The processors are grouped into nodes, which operate semi-independently of each other. Each node has it&#039;s own disk (accessed at /scratch/) and memory, but is capable of communicating with other nodes through a network. When you login to sinister with SSH, you are logged into the head node. This is a special node designed for interacting with users. The other nodes are compute nodes, designed for running long and intensive tasks. SLURM (Simple Linux Utility for Resource Management), now officially called the Slurm Workload Manager, is a programme that manages the compute nodes, allocating resources, starting and ending jobs, and managing the queue. To get the compute nodes to do anything, you need to ask through SLURM.&lt;br /&gt;
&lt;br /&gt;
==How to not be anti-social==&lt;br /&gt;
&lt;br /&gt;
When you are using sinister, the most important thing to be aware of is that other people are using it too. You need to be careful to not act in a way that impedes other users from getting on with their work. Primarily this means not excessively using the head node, as if you do other users will get a very slow response time on their SSH and will not be able to operate. There are some specific things to avoid.&lt;br /&gt;
&lt;br /&gt;
*Do not run long expensive tasks on the head node: that is what the compute nodes are for. Anything longer than a few minutes should not be run on the head node. For a short expensive task (like compiling GMIN), prefix your command with &#039;nice&#039;, which tells the operating system to give your process a lower priority, meaning any simple commands other people might be running are not slowed down. You are not likely to notice a significant impact on the speed of your process by doing this.&lt;br /&gt;
&lt;br /&gt;
  $ nice make&lt;br /&gt;
&lt;br /&gt;
*Do not rapidly copy a lot of data over the network. Although the nodes are networked together and moving data between them is a simple process (using NFS, the Network File System), it is relatively slow and is computationally expensive. If you constantly move data over the NFS, for example by writing a verbose log file, other users will notice. This is most likely to be an issue when writing to the directory /sharedscratch/, which is a large working space partition accessible over the network from any partition. Each node has its own space, accessed at /scratch/ on the node, or through /nodescratch/ from the head node. Best practices to avoid this problem are detailed below, but it is mentioned here due to its great importance.&lt;br /&gt;
&lt;br /&gt;
*Be realistic about the requirements for your job. The cluster is a shared resource that is not infinite. To make the most efficient use of the resource, do not do things like request 32 cores for a job that can only make use of 4, or request a time limit of 1 week for a job that will only take 1 hour. The better the information you give to the queuing system, the better it can serve you.&lt;br /&gt;
&lt;br /&gt;
==Submitting a job==&lt;br /&gt;
&lt;br /&gt;
To submit a job, you create a job submission script, here we&#039;ll call it submit.sh, and then run&lt;br /&gt;
&lt;br /&gt;
  $ sbatch submit.sh&lt;br /&gt;
&lt;br /&gt;
which tells SLURM to execute the contents of your submission script. When you do this, SLURM will first look through any information at the top of the job script for configuration instructions like the job time limit. Then it will place your job into a queue. When the necessary resources become available, any commands in your submission script will be executed in sequence on a compute node. Let&#039;s have a look at a simple submission script for running GMIN.&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J GMIN_LJ38&lt;br /&gt;
  #SBATCH --time=1:00:00&lt;br /&gt;
  #SBATCH -n1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/data $SLURM_SUBMIT_DIR/coords $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/bin/GMIN &amp;gt; logfile&lt;br /&gt;
  &lt;br /&gt;
  cp -p lowest logfile $SLURM_SUBMIT_DIR &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR&lt;br /&gt;
&lt;br /&gt;
We&#039;ll go through this line by line. The first line (affectionately known as the &#039;shebang&#039;) tells SLURM what shell to use to interpret the commands. You don&#039;t have to use Bash, but it&#039;s what most people are used to, so it&#039;s recommended if you want anyone else to be able to help you.&lt;br /&gt;
&lt;br /&gt;
Next we have a series of configuration commands for SLURM. Each of these starts with #SBATCH and they are ignored by Bash. Some of the most useful are:&lt;br /&gt;
&lt;br /&gt;
* -J &amp;lt;name&amp;gt;  The name of the job, that will show up in diagnostic information. Make your life easier by choosing a suitably descriptive one.&lt;br /&gt;
* --time=hh:mm:ss The maximum amount of time your job will run for. If this time limit is reached and the job hasn&#039;t finished, SLURM will kill it. It is in yours and everyone else&#039;s interest to make this a fairly accurate estimate of how long the job will actually take (plus a little bit).&lt;br /&gt;
* --ntasks=&amp;lt;number&amp;gt; The number of processors your job requires.&lt;br /&gt;
* --nodes=&amp;lt;number&amp;gt; The number of nodes your job requires.&lt;br /&gt;
* --mem=&amp;lt;value&amp;gt; The amount of memory your job needs. The default is often fine.&lt;br /&gt;
&lt;br /&gt;
Consult the SLURM documentation [https://slurm.schedmd.com/sbatch.html] for a full list. Here, we request one processor, for a maximum time of 1 hour, and we set the name to &#039;GMIN_LJ38&#039;.&lt;br /&gt;
&lt;br /&gt;
The remaining commands are executed by Bash once the job has begun. First we write out some diagnostic information: the ID of the job and which compute node it is running on. This is written to a file slurm-&amp;lt;job_ID&amp;gt;.out in the directory we run sbatch from, for example&lt;br /&gt;
&lt;br /&gt;
  $ cat slurm-214233.out&lt;br /&gt;
  Starting job 214233&lt;br /&gt;
  compute-0-17.local&lt;br /&gt;
&lt;br /&gt;
The first line is a useful check that the job actually began. Knowing which node your job ran on can be useful if it terminates early/unexpectedly.&lt;br /&gt;
&lt;br /&gt;
The next section of the submission script is about reducing the NFS load. Instead of running the job on /sharedscratch/, which the node accesses over the NFS, we create a directory in the node&#039;s own /scratch/ space. Change &#039;jwrm2&#039; to your own username. We copy only the files GMIN needs in order to run, then change to the new directory. $SLURM_SUBMIT_DIR is a variable holding the directory from whcih sbatch was run.&lt;br /&gt;
&lt;br /&gt;
Next we actually run the programme. We redirect the GMIN output to a log file. If you do not do this redirection, output will instead go to the slurm-&amp;lt;job_ID&amp;gt;.out file, which most likely resides on /sharedscratch/.&lt;br /&gt;
&lt;br /&gt;
Finally, we have clean up actions to be run after GMIN has finished. We copy back only the data we are interested in to the directory from which sbatch was run, then delete the temporary directory we created on the nodescratch. Note the &#039;&amp;amp;&amp;amp;&#039; syntax, which means &#039;run the command after the &amp;amp;&amp;amp; only if the command before the &amp;amp;&amp;amp; was successful&#039;. In this case, it means that the temporary directory will not be deleted if we couldn&#039;t copy those files back.&lt;br /&gt;
&lt;br /&gt;
==The queuing system==&lt;br /&gt;
&lt;br /&gt;
When you submit your job with sbatch, it may not be run instantly. It is quite possible that the the resources your job needs are currently being used by someone else. Your job enters the queue. You can see the queue by typing&lt;br /&gt;
&lt;br /&gt;
  $ squeue&lt;br /&gt;
               JOBID PARTITION                                               NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
              214233   CLUSTER                                          GMIN_LJ38    jwrm2 PD       0:00      1 (Resources)&lt;br /&gt;
              214207   CLUSTER                                              GLP-1    kr366  R      29:31      2 compute-0-[22-23]&lt;br /&gt;
              214112   CLUSTER                                    pentamer_1_1292    ld506  R 1-02:03:44      1 compute-0-12&lt;br /&gt;
&lt;br /&gt;
There is a lot of information here. The first column gives the ID of the job. The next column is not usually relevant. Then we see the name of the job (assigned with -J in the submission script) and the user who submitted the job. The ST column tells you the current status of the job: &#039;PD&#039; means &#039;pending&#039;, ie. the job is waiting to run, but is not yet running; &#039;R&#039; means &#039;running&#039;. We also have the time the job has been running for, the number of nodes the job is using and which they are. If the job is not running, the final column may display a reason. If it shows (Resources), then your job will run as soon as the necessary resources are available. If it instead shows (Priority), then there is another waiting job in the queue that will be run before yours. If you only want to see information about your jobs (or any other user&#039;s), you can use the -u option:&lt;br /&gt;
&lt;br /&gt;
  $ squeue -u jwrm2&lt;br /&gt;
&lt;br /&gt;
will only show the jobs submitted by the user jwrm2.&lt;br /&gt;
&lt;br /&gt;
How does SLURM decide which jobs to run? Principally, it works out a user&#039;s priority by a fairshare system: the more compute time you have recently used, the lower your priority will be. You can see everyone&#039;s fairshare values by looking at the final column of the output of&lt;br /&gt;
&lt;br /&gt;
  $ sshare -a&lt;br /&gt;
&lt;br /&gt;
Higher numbers mean a higher priority for that user. However, SLURM will also try to fit smaller jobs into gaps. If there is a 12 node job waiting from a user with a very high priority, but only one node is currently available, a short one node job from a user with low priority may be able to fit in. Therefore it is in your interest to make realistic estimates of the resources your job needs: it may end up running sooner.&lt;br /&gt;
&lt;br /&gt;
==Oops, I just submitted the wrong job==&lt;br /&gt;
&lt;br /&gt;
You can abort a job when it is waiting to run or when it is running. Find the job ID, either by looking at squeue or the output file in the submission directory. Let&#039;s say it was 214233:&lt;br /&gt;
&lt;br /&gt;
  $ scancel 214233&lt;br /&gt;
&lt;br /&gt;
will immediately kill the job.&lt;br /&gt;
&lt;br /&gt;
==Running PATHSAMPLE with SLURM==&lt;br /&gt;
&lt;br /&gt;
PATHSAMPLE runs a little differently from standard GMIN: it launches new OPTIM jobs and sends them to the other processors available. This is pretty much taken care of if you include &#039;SLURM&#039; in the pathdata file, but there are a couple of extra considerations. Firstly, PATHSAMPLE needs a nodes.info file with information about the available processors. Generate this file at the start of you submission script with:&lt;br /&gt;
&lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
&lt;br /&gt;
Note the use of srun here. It means: run this command on every one of the available processors.&lt;br /&gt;
&lt;br /&gt;
Secondly, we need to decide whether PATHSAMPLE itself will be run from /sharedscratch/ (not the OPTIM jobs, PATHSAMPLE will always use /nodescratch/ for those). Running PATHSAMPLE from /sharedscratch/ is simpler and it means that if the job terminates before PATHSAMPLE completes all the requested cycles, the database on /sharedscratch/ will be in the most current state. Here is an example PATHSAMPLE script that does this&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH --time=20:0:0&lt;br /&gt;
  #SBATCH --job-name=PATHSAMPLE_LJ38&lt;br /&gt;
  #SBATCH --ntasks=16&lt;br /&gt;
  &lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm/bin/PATHSAMPLE &amp;gt; logfile&lt;br /&gt;
&lt;br /&gt;
We run PATHSAMPLE for 20 hours on 16 cores. SLURM is free to assign those cores over multiple nodes as it sees fit. Note there is no creation of a temporary directory on /scratch/, PATHSAMPLE access the database stored in /sharedscratch/. Whenever an OPTIM job is created, PATHSAMPLE creates a temporary directory on /scratch/, copies the files required for OPTIM to run, launches OPTIM with srun, waits for OPTIM to finish, copies the files back and adds new stationary points to the database, then deletes the temporary directory. That is all taken care of for you. Because this approach involves writing to /sharedscratch/, it is only appropriate if each OPTIM job takes a while to run (more than a few minutes) and if the amount of data required for each OPTIM job is small. If either of those conditions is violated, users may notice a slowdown on the head node and be annoyed with you. In that case a different approach is required.&lt;br /&gt;
&lt;br /&gt;
PATHSAMPLE can be run from /nodescratch/. This method reduces the NFS load, but is slightly more complicated and if the job terminates early, you will need to get your expanded database manually (see [[Getting started with SLURM#My job got cancelled, where are my files? | here]]). Here is an example PATHSAMPLE script that does this&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J PATHSAMPLE_LJ38&lt;br /&gt;
  #SBATCH --time=20:0:0&lt;br /&gt;
  #SBATCH --ntask=4&lt;br /&gt;
  #SBATCH --nodes=1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/pathdata $SLURM_SUBMIT_DIR/min.data $SLURM_SUBMIT_DIR/ts.data $SLURM_SUBMIT_DIR/points.min $SLURM_SUBMIT_DIR/points.ts $SLURM_SUBMIT_DIR/min.A $SLURM_SUBMIT_DIR/min.B $SLURM_SUBMIT_DIR/odata.connect $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/svn/PATHSAMPLE/builds/gfortran/PATHSAMPLE &amp;gt; logfile&lt;br /&gt;
  &lt;br /&gt;
  cp min.data ts.data points.min points.ts min.A min.B logfile $SLURM_SUBMIT_DIR/ &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR/&lt;br /&gt;
&lt;br /&gt;
We run for 20 hours on 4 cores. Since we are worried about the amount of data we&#039;re copying around, it makes sense to request these on the same node. We create a temporary directory on the node&#039;s /scratch/ space and copy the whole PATHSAMPLE database to it. Then we generate the nodes.info file and we&#039;re ready to run PATHSAMPLE itself. At the end, we copy the whole database back to /sharedscratch/ and delete the temporary directory if successful. This solution is not perfect, as we still have to copy the whole database over the NFS at the start and the end, but if each OPTIM job needs a lot of writing, or writes data very rapdily, it may be preferable.&lt;br /&gt;
&lt;br /&gt;
==My job got cancelled, where are my files?==&lt;br /&gt;
&lt;br /&gt;
If your job has finished, it will no longer appear in the output of squeue. It may have successfully completed, or it might have run out of time (or memory, etc.). Look at the end of the slurm-&amp;lt;job_ID&amp;gt;.out file. If it shows&lt;br /&gt;
&lt;br /&gt;
  slurmstepd: *** JOB 214233 ON compute-0-36 CANCELLED AT 2020-05-18T10:45:16 DUE TO TIME LIMIT ***&lt;br /&gt;
&lt;br /&gt;
then your job ran out of time and was killed. Maybe this was a week long GMIN run that ran out of time 10 steps from the end. How annoying. Time to run it again from the beginning with a longer time limit, because there is no GMIN.dump file in the submission directory? Hardly... In our job submission script, we only deleted the temporary directory after the successful completion of the job. Therefore if the job did not successfully complete, the directory and its contents are still there. The information at the top of the slurm-&amp;lt;job_ID&amp;gt;.out file will help you find them. We created the temporary directory at&lt;br /&gt;
&lt;br /&gt;
  /scratch/jwrm2/214233&lt;br /&gt;
&lt;br /&gt;
To access this from the head node, we need to know what node it was created on. That&#039;s why we ran &#039;hostname&#039; at the start of the job. Let&#039;s say the output of that was&lt;br /&gt;
&lt;br /&gt;
  compute-0-17.local&lt;br /&gt;
&lt;br /&gt;
We can access our files at&lt;br /&gt;
&lt;br /&gt;
  /nodescratch/compute-0-17/jwrm2/214233&lt;br /&gt;
&lt;br /&gt;
Note that normal Bash tab completion of the directory name may not work here. That doesn&#039;t necessarily mean the directory doesn&#039;t exist, it&#039;s just a peculiarity of NFS automount.&lt;br /&gt;
&lt;br /&gt;
It would be polite to delete the temporary directory after recovering any files you need.&lt;br /&gt;
&lt;br /&gt;
==A smarter way to get your files==&lt;br /&gt;
&lt;br /&gt;
Although recovering files from /nodescratch/ is fine, if you&#039;ve every had 52 GMIN jobs terminate and needed to recover their GMIN.dump files for restarting, it gets a little tedious. Fortunately there is a better way, leveraging the signal mechanism of Linux. Here is an example:&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J GMIN_LJ38&lt;br /&gt;
  #SBATCH --time=5:00&lt;br /&gt;
  #SBATCH -n1&lt;br /&gt;
  #SBATCH --signal=B:USR1@120&lt;br /&gt;
  &lt;br /&gt;
  signal_handler()&lt;br /&gt;
  {&lt;br /&gt;
      # Timeout commands go here&lt;br /&gt;
      echo &amp;quot;Caught USR1 signal&amp;quot;&lt;br /&gt;
      cp GMIN.dump logfile $SLURM_SUBMIT_DIR&lt;br /&gt;
      exit&lt;br /&gt;
  }&lt;br /&gt;
  trap &#039;signal_handler&#039; USR1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/data $SLURM_SUBMIT_DIR/coords $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/bin/GMIN &amp;gt; logfile &amp;amp;&lt;br /&gt;
  wait&lt;br /&gt;
  &lt;br /&gt;
  cp -p lowest logfile $SLURM_SUBMIT_DIR &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR&lt;br /&gt;
&lt;br /&gt;
This script will run any commands enclosed in braces at &#039;# Timeout commands go here&#039;, 120 seconds before the job times out. It will terminate itself immediately after completing those commands, so you will not get a &#039;CANCELLED&#039; message in the slurm-&amp;lt;job_ID&amp;gt;.out file (but only because of the &#039;exit&#039;, otherwise it would continue execution after the &#039;wait&#039;, which is probably not what you want). You can use it to copy back recovery files like GMIN.dump, or the updated PATHSAMPLE database, before the job terminates. If 120 seconds is not enough time for your timeout commands, change the 120 in the line &#039;#SBATCH --signal=B:USR1@120&#039;. The temporary directory will not be deleted if the timeout is reached, although you could put &#039;rm -rf $TMP&#039; in the timeout section if you were really confident that you were grabbing everything you needed. You should occasionally go through /nodescratch/ and delete any leftover temporary directories that may be hanging around.&lt;br /&gt;
&lt;br /&gt;
===Theory===&lt;br /&gt;
&lt;br /&gt;
You don&#039;t need to understand how the above example works to use it, but we&#039;re all curious scientists, aren&#039;t we? The Linux kernel can communicate with a running process by sending it &#039;signals&#039;. Common ones include &#039;SIGTERM&#039; and &#039;SIGKILL&#039;. In fact, when your job reaches the time limit, it gets sent a &#039;SIGTERM&#039; signal, telling it to terminate. If the process has not set up anything specific to do on receiving a particular signal, the default action is to exit. However, most signals can have custom responses set up. An exception is &#039;SIGKILL&#039;, for which immediate termination cannot be overridden. &lt;br /&gt;
&lt;br /&gt;
The line &#039;#SBATCH --signal=B:USR1@120&#039; tells SLURM to please send the signal &#039;USR1&#039; (user specified signal number 1) to the job 120 seconds before reaching the time limit. &#039;USR1&#039; is not sent by any system processes, so we&#039;re free to use it as we wish. Next we create a Bash function, &#039;signal_handler()&#039;, with our sequence of commands. We tell the Bash script to jump to our function on receiving the &#039;USR1&#039; signal, overriding the default exit behaviour (trap &#039;signal_handler&#039; USR1).&lt;br /&gt;
&lt;br /&gt;
The final finicky bit is how we run our main programme. If we ran &#039;GMIN&#039;, the signal would get sent to GMIN, as the active process, rather than Bash. GMIN wouldn&#039;t know what to do with it, so would immediately exit. Not good. By running &#039;GMIN &amp;amp;&#039; instead, the signal goes to Bash. However, if we did just that, the job would quickly reach the end after launching GMIN, which would terminate the job and all it&#039;s children, including GMIN. Oops. By writing &#039;wait&#039;, we tell Bash to go into an &#039;interruptible sleep&#039;, meaning it will sit there not doing anything until it receives a signal. Therefore it is able to excecute the commands in the &#039;signal_handler()&#039; function on receiving the &#039;USR1&#039; signal. As a matter of interest, execution of the main script then resumes where it left off before the signal, but the wait has now been completed (it only waits for the first signal) and execution proceeds to the &#039;cp&#039; line. Putting &#039;exit&#039; at the end of the function means we don&#039;t jump back to after wait. We could have put another &#039;wait&#039; instead of &#039;exit&#039;, but that would only be useful if GMIN finished in the short period of time between completing the function and reaching the job time limit. Better to just save 2 minutes of CPU time by exiting immediately.&lt;br /&gt;
&lt;br /&gt;
How does our job finish normally, if we&#039;ve put it to sleep then? Well, when GMIN exits it sends, you guessed it... a signal, in this case &#039;SIGCHLD&#039;. That will wake up Bash from its wait and the script will proceed to completion.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Getting_started_with_SLURM&amp;diff=1601</id>
		<title>Getting started with SLURM</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Getting_started_with_SLURM&amp;diff=1601"/>
		<updated>2020-05-26T13:22:52Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Added links to other pages with queuing information.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For running computationally expensive tasks for long periods of time, you will want to create a job and run it on a cluster. This page is intended to teach you everything required to run your first job on a SLURM CPU cluster (sinister, volkhan). For convenience, we will refer primarily to sinister, but the information is transferrable to other SLURM clusters, with a small note about SLURM versions [[A guide to using SLURM to run PATHSAMPLE | here]]. This page does not contain information about PBS (dexter), but there is some information [[Submitting jobs, interactively or to a cluster queue system | here]]. If you are running GPU (pat) jobs, you will need additional information from [[A guide to using SLURM to run GPU jobs on pat | here]].&lt;br /&gt;
&lt;br /&gt;
==Basic terminology==&lt;br /&gt;
&lt;br /&gt;
A cluster is a large computer that has many processors. The processors are grouped into nodes, which operate semi-independently of each other. Each node has it&#039;s own disk (accessed at /scratch/) and memory, but is capable of communicating with other nodes through a network. When you login to sinister with SSH, you are logged into the head node. This is a special node designed for interacting with users. The other nodes are compute nodes, designed for running long and intensive tasks. SLURM (Simple Linux Utility for Resource Management), now officially called the Slurm Workload Manager, is a programme that manages the compute nodes, allocating resources, starting and ending jobs, and managing the queue. To get the compute nodes to do anything, you need to ask through SLURM.&lt;br /&gt;
&lt;br /&gt;
==How to not be anti-social==&lt;br /&gt;
&lt;br /&gt;
When you are using sinister, the most important thing to be aware of is that other people are using it too. You need to be careful to not act in a way that impedes other users from getting on with their work. Primarily this means not excessively using the head node, as if you do other users will get a very slow response time on their SSH and will not be able to operate. There are some specific things to avoid.&lt;br /&gt;
&lt;br /&gt;
*Do not run long expensive tasks on the head node: that is what the compute nodes are for. Anything longer than a few minutes should not be run on the head node. For a short expensive task (like compiling GMIN), prefix your command with &#039;nice&#039;, which tells the operating system to give your process a lower priority, meaning any simple commands other people might be running are not slowed down. You are not likely to notice a significant impact on the speed of your process by doing this.&lt;br /&gt;
&lt;br /&gt;
  $ nice make&lt;br /&gt;
&lt;br /&gt;
*Do not rapidly copy a lot of data over the network. Although the nodes are networked together and moving data between them is a simple process (using NFS, the Network File System), it is relatively slow and is computationally expensive. If you constantly move data over the NFS, for example by writing a verbose log file, other users will notice. This is most likely to be an issue when writing to the directory /sharedscratch/, which is a large working space partition accessible over the network from any partition. Each node has its own space, accessed at /scratch/ on the node, or through /nodescratch/ from the head node. Best practices to avoid this problem are detailed below, but it is mentioned here due to its great importance.&lt;br /&gt;
&lt;br /&gt;
*Be realistic about the requirements for your job. The cluster is a shared resource that is not infinite. To make the most efficient use of the resource, do not do things like request 32 cores for a job that can only make use of 4, or request a time limit of 1 week for a job that will only take 1 hour. The better the information you give to the queuing system, the better it can serve you.&lt;br /&gt;
&lt;br /&gt;
==Submitting a job==&lt;br /&gt;
&lt;br /&gt;
To submit a job, you create a job submission script, here we&#039;ll call it submit.sh, and then run&lt;br /&gt;
&lt;br /&gt;
  $ sbatch submit.sh&lt;br /&gt;
&lt;br /&gt;
which tells SLURM to execute the contents of your submission script. When you do this, SLURM will first look through any information at the top of the job script for configuration instructions like the job time limit. Then it will place your job into a queue. When the necessary resources become available, any commands in your submission script will be executed in sequence on a compute node. Let&#039;s have a look at a simple submission script for running GMIN.&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J GMIN_LJ38&lt;br /&gt;
  #SBATCH --time=1:00:00&lt;br /&gt;
  #SBATCH -n1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/data $SLURM_SUBMIT_DIR/coords $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/bin/GMIN &amp;gt; logfile&lt;br /&gt;
  &lt;br /&gt;
  cp -p lowest logfile $SLURM_SUBMIT_DIR &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR&lt;br /&gt;
&lt;br /&gt;
We&#039;ll go through this line by line. The first line (affectionately known as the &#039;shebang&#039;) tells SLURM what shell to use to interpret the commands. You don&#039;t have to use Bash, but it&#039;s what most people are used to, so it&#039;s recommended if you want anyone else to be able to help you.&lt;br /&gt;
&lt;br /&gt;
Next we have a series of configuration commands for SLURM. Each of these starts with #SBATCH and they are ignored by Bash. Some of the most useful are:&lt;br /&gt;
&lt;br /&gt;
* -J &amp;lt;name&amp;gt;  The name of the job, that will show up in diagnostic information. Make your life easier by choosing a suitably descriptive one.&lt;br /&gt;
* --time=hh:mm:ss The maximum amount of time your job will run for. If this time limit is reached and the job hasn&#039;t finished, SLURM will kill it. It is in yours and everyone else&#039;s interest to make this a fairly accurate estimate of how long the job will actually take (plus a little bit).&lt;br /&gt;
* --ntasks=&amp;lt;number&amp;gt; The number of processors your job requires.&lt;br /&gt;
* --nodes=&amp;lt;number&amp;gt; The number of nodes your job requires.&lt;br /&gt;
* --mem=&amp;lt;value&amp;gt; The amount of memory your job needs. The default is often fine.&lt;br /&gt;
&lt;br /&gt;
Consult the SLURM documentation [https://slurm.schedmd.com/sbatch.html] for a full list. Here, we request one processor, for a maximum time of 1 hour, and we set the name to &#039;GMIN_LJ38&#039;.&lt;br /&gt;
&lt;br /&gt;
The remaining commands are executed by Bash once the job has begun. First we write out some diagnostic information: the ID of the job and which compute node it is running on. This is written to a file slurm-&amp;lt;job_ID&amp;gt;.out in the directory we run sbatch from, for example&lt;br /&gt;
&lt;br /&gt;
  $ cat slurm-214233.out&lt;br /&gt;
  Starting job 214233&lt;br /&gt;
  compute-0-17.local&lt;br /&gt;
&lt;br /&gt;
The first line is a useful check that the job actually began. Knowing which node your job ran on can be useful if it terminates early/unexpectedly.&lt;br /&gt;
&lt;br /&gt;
The next section of the submission script is about reducing the NFS load. Instead of running the job on /sharedscratch/, which the node accesses over the NFS, we create a directory in the node&#039;s own /scratch/ space. Change &#039;jwrm2&#039; to your own username. We copy only the files GMIN needs in order to run, then change to the new directory. $SLURM_SUBMIT_DIR is a variable holding the directory from whcih sbatch was run.&lt;br /&gt;
&lt;br /&gt;
Next we actually run the programme. We redirect the GMIN output to a log file. If you do not do this redirection, output will instead go to the slurm-&amp;lt;job_ID&amp;gt;.out file, which most likely resides on /sharedscratch/.&lt;br /&gt;
&lt;br /&gt;
Finally, we have clean up actions to be run after GMIN has finished. We copy back only the data we are interested in to the directory from which sbatch was run, then delete the temporary directory we created on the nodescratch. Note the &#039;&amp;amp;&amp;amp;&#039; syntax, which means &#039;run the command after the &amp;amp;&amp;amp; only if the command before the &amp;amp;&amp;amp; was successful&#039;. In this case, it means that the temporary directory will not be deleted if we couldn&#039;t copy those files back.&lt;br /&gt;
&lt;br /&gt;
==The queuing system==&lt;br /&gt;
&lt;br /&gt;
When you submit your job with sbatch, it may not be run instantly. It is quite possible that the the resources your job needs are currently being used by someone else. Your job enters the queue. You can see the queue by typing&lt;br /&gt;
&lt;br /&gt;
  $ squeue&lt;br /&gt;
               JOBID PARTITION                                               NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
              214233   CLUSTER                                          GMIN_LJ38    jwrm2 PD       0:00      1 (Resources)&lt;br /&gt;
              214207   CLUSTER                                              GLP-1    kr366  R      29:31      2 compute-0-[22-23]&lt;br /&gt;
              214112   CLUSTER                                    pentamer_1_1292    ld506  R 1-02:03:44      1 compute-0-12&lt;br /&gt;
&lt;br /&gt;
There is a lot of information here. The first column gives the ID of the job. The next column is not usually relevant. Then we see the name of the job (assigned with -J in the submission script) and the user who submitted the job. The ST column tells you the current status of the job: &#039;PD&#039; means &#039;pending&#039;, ie. the job is waiting to run, but is not yet running; &#039;R&#039; means &#039;running&#039;. We also have the time the job has been running for, the number of nodes the job is using and which they are. If the job is not running, the final column may display a reason. If it shows (Resources), then your job will run as soon as the necessary resources are available. If it instead shows (Priority), then there is another waiting job in the queue that will be run before yours. If you only want to see information about your jobs (or any other user&#039;s), you can use the -u option:&lt;br /&gt;
&lt;br /&gt;
  $ squeue -u jwrm2&lt;br /&gt;
&lt;br /&gt;
will only show the jobs submitted by the user jwrm2.&lt;br /&gt;
&lt;br /&gt;
How does SLURM decide which jobs to run? Principally, it works out a user&#039;s priority by a fairshare system: the more compute time you have recently used, the lower your priority will be. You can see everyone&#039;s fairshare values by looking at the final column of the output of&lt;br /&gt;
&lt;br /&gt;
  $ sshare -a&lt;br /&gt;
&lt;br /&gt;
Higher numbers mean a higher priority for that user. However, SLURM will also try to fit smaller jobs into gaps. If there is a 12 node job waiting from a user with a very high priority, but only one node is currently available, a short one node job from a user with low priority may be able to fit in. Therefore it is in your interest to make realistic estimates of the resources your job needs: it may end up running sooner.&lt;br /&gt;
&lt;br /&gt;
==Oops, I just submitted the wrong job==&lt;br /&gt;
&lt;br /&gt;
You can abort a job when it is waiting to run or when it is running. Find the job ID, either by looking at squeue or the output file in the submission directory. Let&#039;s say it was 214233:&lt;br /&gt;
&lt;br /&gt;
  $ scancel 214233&lt;br /&gt;
&lt;br /&gt;
will immediately kill the job.&lt;br /&gt;
&lt;br /&gt;
==Running PATHSAMPLE with SLURM==&lt;br /&gt;
&lt;br /&gt;
PATHSAMPLE runs a little differently from standard GMIN: it launches new OPTIM jobs and sends them to the other processors available. This is pretty much taken care of if you include &#039;SLURM&#039; in the pathdata file, but there are a couple of extra considerations. Firstly, PATHSAMPLE needs a nodes.info file with information about the available processors. Generate this file at the start of you submission script with:&lt;br /&gt;
&lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
&lt;br /&gt;
Note the use of srun here. It means: run this command on every one of the available processors.&lt;br /&gt;
&lt;br /&gt;
Secondly, we need to decide whether PATHSAMPLE itself will be run from /sharedscratch/ (not the OPTIM jobs, PATHSAMPLE will always use /nodescratch/ for those). Running PATHSAMPLE from /sharedscratch/ is simpler and it means that if the job terminates before PATHSAMPLE completes all the requested cycles, the database on /sharedscratch/ will be in the most current state. Here is an example PATHSAMPLE script that does this&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH --time=20:0:0&lt;br /&gt;
  #SBATCH --job-name=PATHSAMPLE_LJ38&lt;br /&gt;
  #SBATCH --ntasks=16&lt;br /&gt;
  &lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm/bin/PATHSAMPLE &amp;gt; logfile&lt;br /&gt;
&lt;br /&gt;
We run PATHSAMPLE for 20 hours on 16 cores. SLURM is free to assign those cores over multiple nodes as it sees fit. Note there is no creation of a temporary directory on /scratch/, PATHSAMPLE access the database stored in /sharedscratch/. Whenever an OPTIM job is created, PATHSAMPLE creates a temporary directory on /scratch/, copies the files required for OPTIM to run, launches OPTIM with srun, waits for OPTIM to finish, copies the files back and adds new stationary points to the database, then deletes the temporary directory. That is all taken care of for you. Because this approach involves writing to /sharedscratch/, it is only appropriate if each OPTIM job takes a while to run (more than a few minutes) and if the amount of data required for each OPTIM job is small. If either of those conditions is violated, users may notice a slowdown on the head node and be annoyed with you. In that case a different approach is required.&lt;br /&gt;
&lt;br /&gt;
PATHSAMPLE can be run from /nodescratch/. This method reduces the NFS load, but is slightly more complicated and if the job terminates early, you will need to get your expanded database manually (see [[Getting started with SLURM#My job got cancelled, where are my files? | here]]). Here is an example PATHSAMPLE script that does this&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J PATHSAMPLE_LJ38&lt;br /&gt;
  #SBATCH --time=20:0:0&lt;br /&gt;
  #SBATCH --ntask=4&lt;br /&gt;
  #SBATCH --nodes=1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/pathdata $SLURM_SUBMIT_DIR/min.data $SLURM_SUBMIT_DIR/ts.data $SLURM_SUBMIT_DIR/points.min $SLURM_SUBMIT_DIR/points.ts $SLURM_SUBMIT_DIR/min.A $SLURM_SUBMIT_DIR/min.B $SLURM_SUBMIT_DIR/odata.connect $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/svn/PATHSAMPLE/builds/gfortran/PATHSAMPLE &amp;gt; logfile&lt;br /&gt;
  &lt;br /&gt;
  cp min.data ts.data points.min points.ts min.A min.B logfile $SLURM_SUBMIT_DIR/ &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR/&lt;br /&gt;
&lt;br /&gt;
We run for 20 hours on 4 cores. Since we are worried about the amount of data we&#039;re copying around, it makes sense to request these on the same node. We create a temporary directory on the node&#039;s /scratch/ space and copy the whole PATHSAMPLE database to it. Then we generate the nodes.info file and we&#039;re ready to run PATHSAMPLE itself. At the end, we copy the whole database back to /sharedscratch/ and delete the temporary directory if successful. This solution is not perfect, as we still have to copy the whole database over the NFS at the start and the end, but if each OPTIM job needs a lot of writing, or writes data very rapdily, it may be preferable.&lt;br /&gt;
&lt;br /&gt;
==My job got cancelled, where are my files?==&lt;br /&gt;
&lt;br /&gt;
If your job has finished, it will no longer appear in the output of squeue. It may have successfully completed, or it might have run out of time (or memory, etc.). Look at the end of the slurm-&amp;lt;job_ID&amp;gt;.out file. If it shows&lt;br /&gt;
&lt;br /&gt;
  slurmstepd: *** JOB 214233 ON compute-0-36 CANCELLED AT 2020-05-18T10:45:16 DUE TO TIME LIMIT ***&lt;br /&gt;
&lt;br /&gt;
then your job ran out of time and was killed. Maybe this was a week long GMIN run that ran out of time 10 steps from the end. How annoying. Time to run it again from the beginning with a longer time limit, because there is no GMIN.dump file in the submission directory? Hardly... In our job submission script, we only deleted the temporary directory after the successful completion of the job. Therefore if the job did not successfully complete, the directory and its contents are still there. The information at the top of the slurm-&amp;lt;job_ID&amp;gt;.out file will help you find them. We created the temporary directory at&lt;br /&gt;
&lt;br /&gt;
  /scratch/jwrm2/214233&lt;br /&gt;
&lt;br /&gt;
To access this from the head node, we need to know what node it was created on. That&#039;s why we ran &#039;hostname&#039; at the start of the job. Let&#039;s say the output of that was&lt;br /&gt;
&lt;br /&gt;
  compute-0-17.local&lt;br /&gt;
&lt;br /&gt;
We can access our files at&lt;br /&gt;
&lt;br /&gt;
  /nodescratch/compute-0-17/jwrm2/214233&lt;br /&gt;
&lt;br /&gt;
Note that normal Bash tab completion of the directory name may not work here. That doesn&#039;t necessarily mean the directory doesn&#039;t exist, it&#039;s just a peculiarity of NFS automount.&lt;br /&gt;
&lt;br /&gt;
It would be polite to delete the temporary directory after recovering any files you need.&lt;br /&gt;
&lt;br /&gt;
==A smarter way to get your files==&lt;br /&gt;
&lt;br /&gt;
Although recovering files from /nodescratch/ is fine, if you&#039;ve every had 52 GMIN jobs terminate and needed to recover their GMIN.dump files for restarting, it gets a little tedious. Fortunately there is a better way, leveraging the signal mechanism of Linux. Here is an example:&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J GMIN_LJ38&lt;br /&gt;
  #SBATCH --time=5:00&lt;br /&gt;
  #SBATCH -n1&lt;br /&gt;
  #SBATCH --signal=B:USR1@120&lt;br /&gt;
  &lt;br /&gt;
  signal_handler()&lt;br /&gt;
  {&lt;br /&gt;
      # Timeout commands go here&lt;br /&gt;
      echo &amp;quot;Caught USR1 signal&amp;quot;&lt;br /&gt;
      cp GMIN.dump logfile $SLURM_SUBMIT_DIR&lt;br /&gt;
      exit&lt;br /&gt;
  }&lt;br /&gt;
  trap &#039;signal_handler&#039; USR1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/data $SLURM_SUBMIT_DIR/coords $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/bin/GMIN &amp;gt; logfile &amp;amp;&lt;br /&gt;
  wait&lt;br /&gt;
  &lt;br /&gt;
  cp -p lowest logfile $SLURM_SUBMIT_DIR &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR&lt;br /&gt;
&lt;br /&gt;
This script will run any commands enclosed in braces at &#039;# Timeout commands go here&#039;, 120 seconds before the job times out. It will terminate itself immediately after completing those commands, so you will not get a &#039;CANCELLED&#039; message in the slurm-&amp;lt;job_ID&amp;gt;.out file (but only because of the &#039;exit&#039;, otherwise it would continue execution after the &#039;wait&#039;, which is probably not what you want). You can use it to copy back recovery files like GMIN.dump, or the updated PATHSAMPLE database, before the job terminates. If 120 seconds is not enough time for your timeout commands, change the 120 in the line &#039;#SBATCH --signal=B:USR1@120&#039;. The temporary directory will not be deleted if the timeout is reached, although you could put &#039;rm -rf $TMP&#039; in the timeout section if you were really confident that you were grabbing everything you needed. You should occasionally go through /nodescratch/ and delete any leftover temporary directories that may be hanging around.&lt;br /&gt;
&lt;br /&gt;
===Theory===&lt;br /&gt;
&lt;br /&gt;
You don&#039;t need to understand how the above example works to use it, but we&#039;re all curious scientists, aren&#039;t we? The Linux kernel can communicate with a running process by sending it &#039;signals&#039;. Common ones include &#039;SIGTERM&#039; and &#039;SIGKILL&#039;. In fact, when your job reaches the time limit, it gets sent a &#039;SIGTERM&#039; signal, telling it to terminate. If the process has not set up anything specific to do on receiving a particular signal, the default action is to exit. However, most signals can have custom responses set up. An exception is &#039;SIGKILL&#039;, for which immediate termination cannot be overridden. &lt;br /&gt;
&lt;br /&gt;
The line &#039;#SBATCH --signal=B:USR1@120&#039; tells SLURM to please send the signal &#039;USR1&#039; (user specified signal number 1) to the job 120 seconds before reaching the time limit. &#039;USR1&#039; is not sent by any system processes, so we&#039;re free to use it as we wish. Next we create a Bash function, &#039;signal_handler()&#039;, with our sequence of commands. We tell the Bash script to jump to our function on receiving the &#039;USR1&#039; signal, overriding the default exit behaviour (trap &#039;signal_handler&#039; USR1).&lt;br /&gt;
&lt;br /&gt;
The final finicky bit is how we run our main programme. If we ran &#039;GMIN&#039;, the signal would get sent to GMIN, as the active process, rather than Bash. GMIN wouldn&#039;t know what to do with it, so would immediately exit. Not good. By running &#039;GMIN &amp;amp;&#039; instead, the signal goes to Bash. However, if we did just that, the job would quickly reach the end after launching GMIN, whcih would terminate the job and all it&#039;s children, including GMIN. Oops. By writing &#039;wait&#039;, we tell Bash to go into an &#039;interruptible sleep&#039;, meaning it will sit there not doing anything until it receives a signal. Therefore it is able to exceute the commands in the &#039;signal_handler()&#039; function on receiving the &#039;USR1&#039; signal. As a matter of interest, execution of the main script then resumes where it left off before the signal, but the wait has now been completed (it only waits for the first signal) and execution proceeds to the &#039;cp&#039; line. Putting &#039;exit&#039; at the end of the function means we don&#039;t junp back to after wait. We could have put another &#039;wait&#039; instead of &#039;exit&#039;, but that would only be useful if GMIN finished in the short period of time between completing the function and reaching the job time limit. Better to just save 2 minutes of CPU time by exiting immediately.&lt;br /&gt;
&lt;br /&gt;
How does our job finish normally, if we&#039;ve put it to sleep then? Well, when GMIN exits it sends, you guessed it... a signal, in this case &#039;SIGCHLD&#039;. That will wake up Bash from its wait and the script will proceed to completion.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Comprehensive_Contents_Page&amp;diff=1600</id>
		<title>Comprehensive Contents Page</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Comprehensive_Contents_Page&amp;diff=1600"/>
		<updated>2020-05-26T13:17:24Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: /* Cluster queues */  Added introductory SLURM page.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is designed to organise all of the pages on this wiki, as well as provide other useful links. Note that some pages may appear under more than one heading.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
[[Wales Group]] provides good step-by-step instructions. Relevant pages are:&lt;br /&gt;
&lt;br /&gt;
=== Acquiring and compiling the group software ===&lt;br /&gt;
* [[SVN setup]]&lt;br /&gt;
* [[Wales Group Version control]] - to keep the code standardised.&lt;br /&gt;
* Theory Sector [http://wwmm.ch.cam.ac.uk/wikis/cuc3/index.php/SVN_Page SVN Page] - some useful general information on SVN commands.&lt;br /&gt;
* [[Compiling Wales Group codes using cmake]] - CMake (Cross-platform Make) allows us to compile and test the group codebase regardless of platform. This page provides crucial information how to compile using cmake.&lt;br /&gt;
* [[ElaborateDiff]]&lt;br /&gt;
&lt;br /&gt;
=== Maintaining code health ===&lt;br /&gt;
* [[Jenkins CI]] - explains Jenkins, which we use to download our code and compile each of our targets with each of the compilers every night.&lt;br /&gt;
* https://wales-jenkins.ch.cam.ac.uk/ - log for our Jenkins tests.&lt;br /&gt;
* [[Branching and Merging]]&lt;br /&gt;
* [[Cmake interface building]]&lt;br /&gt;
* [[Installing python modules]]&lt;br /&gt;
* [[Revamping the modules system]]&lt;br /&gt;
&lt;br /&gt;
=== Collaborators without access to the SVN repository ===&lt;br /&gt;
For licensing reasons, some code cannot be included in the Wales Group public tarball.&lt;br /&gt;
* http://www-wales.ch.cam.ac.uk/svn.tar.bz2 - Wales group public tarball. Includes [[GMIN]], [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
If a collaborator has a [[CHARMM]] or [[AMBER]] licence, we do maintain separate tarballs which include the [[CHARMM]], [[AMBER]] and [[CHARMM]]+[[AMBER]] source and interfaces. These are not linked anywhere on the website and require a username (&#039;&#039;&#039;wales&#039;&#039;&#039;) and password (&#039;&#039;&#039;group&#039;&#039;&#039;) to download:&lt;br /&gt;
&lt;br /&gt;
* [http://www-wales.ch.cam.ac.uk/CHARMM/svn.CHARMM.tar.bz2 CHARMM]&lt;br /&gt;
* [http://www-wales.ch.cam.ac.uk/AMBER/svn.AMBER.tar.bz2 AMBER]&lt;br /&gt;
* [http://www-wales.ch.cam.ac.uk/both/svn.both.tar.bz2 AMBER+CHARMM]&lt;br /&gt;
&lt;br /&gt;
=== Running on Windows ===&lt;br /&gt;
Not particularly recommended.&lt;br /&gt;
* [[Running Wales Group software on Windows 7]]&lt;br /&gt;
&lt;br /&gt;
== Wales Group Programs ==&lt;br /&gt;
&lt;br /&gt;
=== Programs ===&lt;br /&gt;
* [[GMIN]]: A program for finding global minima and calculating thermodynamic properties from basin-sampling.&lt;br /&gt;
* [[OPTIM]]: A program for optimizing geometries and calculating reaction pathways.&lt;br /&gt;
* [[PATHSAMPLE]]: A driver for OPTIM to create stationary point databases using discrete path sampling and perform kinetic analysis.&lt;br /&gt;
* [[Pele]]: Python energy landscape explorer. A pythonic rewrite of some core functionality of GMIN, OPTIM, and PATHSAMPLE. Can be very useful for visualizing your system and for rapidly implementing and testing new ideas.&lt;br /&gt;
&lt;br /&gt;
=== Curated Examples ===&lt;br /&gt;
* https://github.com/wales-group/examples - set of tutorials detailing how to use GMIN, OPTIM and PATHSAMPLE. Essential for beginners.&lt;br /&gt;
* http://www-wales.ch.cam.ac.uk/VM/Wales_Group_VM.ova - Pre-prepared teaching virtual machine. This contains the code and examples.&lt;br /&gt;
* https://www.virtualbox.org/wiki/Downloads - This is required if using the VM above.&lt;br /&gt;
* https://github.com/wales-group/examples.git - Alternatively, you can run the examples on your own machine. To get hold of the relevant files:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git clone https://github.com/wales-group/examples.git&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Useful Notes on Wales Group Programs and Subroutines ==&lt;br /&gt;
=== [[GMIN]] ===&lt;br /&gt;
* [[Adding a model to GMIN]] - rough outline of the subroutines that need to be changed to add a new model to GMIN&lt;br /&gt;
* [[Compiling Wales Group codes using cmake | Compiling GMIN using cmake ]]&lt;br /&gt;
* [[Selecting search parameters for GMIN]]&lt;br /&gt;
* [[Global optimization of biomolecules using CHARMM]]&lt;br /&gt;
* [[Global optimization of biomolecules using AMBER9]]&lt;br /&gt;
* [[Global optimization of biomolecules using AMBER9 with Structural Restraints]]&lt;br /&gt;
* [[Calculating binding free energy using the FSA method]]&lt;br /&gt;
* [[Restarting a GMIN run from a dump file]]&lt;br /&gt;
* [[Using the implicit membrane model IMM1]]&lt;br /&gt;
* [[Running a Go model with the AMHGMIN]]&lt;br /&gt;
* [[Running a G\=o model with the AMHGMIN]]&lt;br /&gt;
* [[Ligand binding-mode searches with HBONDMATRIX]]&lt;br /&gt;
* [[Compiling and using GMIN with QUIP]]&lt;br /&gt;
* [[Using GMIN and OPTIM with GPUs]]&lt;br /&gt;
* [[Using GMIN to generate endpoints]]&lt;br /&gt;
* [[Using GMIN to generate endpoints (CHARMM)]]&lt;br /&gt;
* [[Generating a GMIN Eclipse project]]&lt;br /&gt;
* [[Mutational BH steps]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[DMAGMIN setup]]&lt;br /&gt;
* [[Keywords]]&lt;br /&gt;
* [[PYGMIN &amp;amp; DMACRYS]]&lt;br /&gt;
* [[Rotamer moves in AMBER]]&lt;br /&gt;
* [[Python interface for GMIN/OPTIM]]&lt;br /&gt;
&lt;br /&gt;
==== Scripts ====&lt;br /&gt;
* [[makerestart]]: A bash script to automatically set up a GMIN restart run&lt;br /&gt;
* [[progress]] A bash script to tell you the % completion of a GMIN job and give an estimated time remaining&lt;br /&gt;
&lt;br /&gt;
==== Useful info for coding GMIN ====&lt;br /&gt;
* [[Program flow]] - contains information about what the various files in GMIN do and what order they&#039;re called. &lt;br /&gt;
* [[amberinterface]]&lt;br /&gt;
&lt;br /&gt;
==== Projects ====&lt;br /&gt;
* [[GMIN MOVES module]]&lt;br /&gt;
* [[GMIN SANITY module]]&lt;br /&gt;
* [[GMIN TESTS module]]&lt;br /&gt;
* [[CAMSHIFT]]&lt;br /&gt;
&lt;br /&gt;
=== [[OPTIM]] ===&lt;br /&gt;
* [[Adding a model to OPTIM]] - rough outline of the subrounties that need to be changed to add a new model to OPTIM&lt;br /&gt;
* [[Adding partially finished OPTIM stationary points to a PATHSAMPLE database]]&lt;br /&gt;
* [[perm-pdb.py]]: A python program that creates a &#039;&#039;perm.allow&#039;&#039; file for use with [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
* [[visualising normal modes using VMD and OPTIM]]&lt;br /&gt;
* [[Compiling Wales Group codes using cmake | Compiling OPTIM using cmake ]]&lt;br /&gt;
* [[OPTIM/Q-Chem Tutorial]]&lt;br /&gt;
* [[OPTIM and PY ellipsoids tutorial]]&lt;br /&gt;
* [[OPTIM output files]]&lt;br /&gt;
* [[Minimizing a structure using OPTIM and AMBER9]]&lt;br /&gt;
* [[Minimizing a structure using OPTIM and CHARMM]]&lt;br /&gt;
* [[Creating movies (.mpg) of paths using OPTIM]]&lt;br /&gt;
* [[Performing a normal mode analysis of a biomolecule using OPTIM (AMBER and CHARMM)]]&lt;br /&gt;
* [[Debugging odd transition states in OPTIM]]&lt;br /&gt;
* [[Connecting two minima with a pathway]] - step by step&lt;br /&gt;
* [[Compiling and using OPTIM with QUIP]]&lt;br /&gt;
* [[Running an Gaussian03 interfaced OPTIM job]]&lt;br /&gt;
* [[The effect of calculating less than the maximum number of eigenvalues using ENDHESS n]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[BLJ60 example setup]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Python interface for GMIN/OPTIM]]&lt;br /&gt;
* [[Thomson problem in OPTIM]]&lt;br /&gt;
* [[Instanton tunneling and classical rate calculations with OPTIM]]&lt;br /&gt;
* [[Loading OPTIM&#039;s min.data.info files into PATHSAMPLE]]&lt;br /&gt;
* [[common setup problem : No Frequency Warning]]&lt;br /&gt;
&lt;br /&gt;
=== [[PATHSAMPLE]] ===&lt;br /&gt;
* [[Adding a model to PATHSAMPLE]] - rough outline of the subrounties that need to be changed to add a new model to PATHSAMPLE&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself]]&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself (CHARMM)]]&lt;br /&gt;
* [[perm-pdb.py]]: A python program that creates a &#039;&#039;perm.allow&#039;&#039; file for use with [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
* [[dijkstra_test.py]]: A python script to test whether the information in pairlist and ts.data connects the A and B set. (If not, PATHSAMPLE will not work without actually exiting.)&lt;br /&gt;
* [[Compiling Wales Group codes using cmake | Compiling PATHSAMPLE using cmake ]]&lt;br /&gt;
* [[IMPORTANT: Using PATHSAMPLE safely on sinister]]&lt;br /&gt;
* [[Adding a model for PATHSAMPLE]]&lt;br /&gt;
* [[List of output files for PATHSAMPLE]]&lt;br /&gt;
* [[Using BHINTERP to find minima between two end points]]&lt;br /&gt;
* [[Finding an initial path between two end points (minima)]]&lt;br /&gt;
* [[Adding partially finished OPTIM stationary points to a PATHSAMPLE database]]&lt;br /&gt;
* [[Optimising a path]]&lt;br /&gt;
* [[Fine tuning UNTRAP]] - ensuring that it picks sensible minima&lt;br /&gt;
* [[Calculating rate constants (GT and fastest path)]]&lt;br /&gt;
* [[Calculating rate constants (SGT, DGT, and SDGT)]]&lt;br /&gt;
* [[Identifying the k fastest paths between endpoints using KSHORTESTPATHS]]&lt;br /&gt;
* [[Removing minima and transition states from the database]]&lt;br /&gt;
* [[Relaxing existing minima with new potential and creating new database]]&lt;br /&gt;
* [[Relaxing existing transition states with new potential and creating new database]]&lt;br /&gt;
* [[If things go wrong...]]&lt;br /&gt;
* [[If you lost file min.data, but still you have points.min]]&lt;br /&gt;
* [[path.info file is not read, causes PATHSAMPLE to die]]&lt;br /&gt;
* [[BLJ60 example setup]]&lt;br /&gt;
* [[When PATHSAMPLE finds a connected path, but using DIJKSTRA 0 fails to find the connected path]]&lt;br /&gt;
* [[Biomolecules in PATHSAMPLE]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[Expanding the kinetic transition network with PATHSAMPLE]]&lt;br /&gt;
* [[Expanding the kinetic transition network with PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Pathsampling short paths]]&lt;br /&gt;
* [[Pathsampling short paths (CHARMM)]]&lt;br /&gt;
* [[Loading OPTIM&#039;s min.data.info files into PATHSAMPLE]]&lt;br /&gt;
* [[Connecting Sub-databases]]&lt;br /&gt;
&lt;br /&gt;
=== [[Notes on MINPERMDIST | MINPERMDIST]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Quasi-continuous interpolation for biomolecules | QCI]] ===&lt;br /&gt;
&lt;br /&gt;
== Non-Group Software ==&lt;br /&gt;
&lt;br /&gt;
=== [[AMBER]] ===&lt;br /&gt;
Molecular dynamics simulation program and associated force fields.&lt;br /&gt;
* [http://ambermd.org/ AMBER]&lt;br /&gt;
* [http://ambermd.org/tutorials/ AMBER tutorials] - recommended reading for &#039;&#039;&#039;ANYONE&#039;&#039;&#039; using AMBER!&lt;br /&gt;
* [[Notes on AMBER 12 interface]]&lt;br /&gt;
* [[Using AMBER 14 on the GPU and compute clusters]]&lt;br /&gt;
* [[Generating parameters using AMBER&#039;s built in General Forcefield (gaff)]]&lt;br /&gt;
* [[Generating parameters using RESP charges from GAMESS-US]]&lt;br /&gt;
* [[Simple scripts for LEaP to create topology and coordinate files]] &lt;br /&gt;
* [[Preparing an AMBER topology file for a protein system]] - step by step guide&lt;br /&gt;
* [[Setting up]] - step by step guide to prepare and then symmetrise a simple (protein-only) system&lt;br /&gt;
* [[Using Molfacture to edit molecules and add hydrogens]]&lt;br /&gt;
* [[Preparing an AMBER topology file for a protein plus ligand system]] - step by step guide&lt;br /&gt;
* [[Symmetrising AMBER topology files]] - step by step guide for symmetrising a complex protein+ligand system&lt;br /&gt;
* [[Producing a PDB from a coordinates and topology file]] - using &#039;&#039;amdpdb&#039;&#039;&lt;br /&gt;
* [[Running GMIN with MD move steps AMBER]]&lt;br /&gt;
* [[Performing a normal mode analysis of a biomolecule using OPTIM (AMBER and CHARMM)]]&lt;br /&gt;
* [[Evaluating different components of AMBER energy function with SANDER]]&lt;br /&gt;
* [[Mutational BH steps]]&lt;br /&gt;
* [[REMD with AMBER]]&lt;br /&gt;
* [[Performing a hydrogen-bond analysis]]&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself]]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
* [[perm-prmtop.py]] - A python program that converts an AMBER9 topology file into one with a symmetrised potential with respect to exchange (updated for AMBER12 and ff14SB).&lt;br /&gt;
* [[Rotamer moves in AMBER]]&lt;br /&gt;
* [[Creating mismatched DNA duplex using NAB]]&lt;br /&gt;
&lt;br /&gt;
=== [[aux2bib]] === &lt;br /&gt;
To generate a bib file containing only the entries cited in a given .tex file from a larger bib or multiple bib files.&lt;br /&gt;
* [https://ctan.org/pkg/bibtools Get script here]&lt;br /&gt;
&lt;br /&gt;
=== [[CamCasp]] ===&lt;br /&gt;
Cambridge package for Calculation of Anisotropic Site Properties&lt;br /&gt;
From Anthony Stone&#039;s website: &#039;CamCASP is a collection of scripts and programs written by Dr Alston Misquitta and myself for the calculation ab initio of distributed multipoles, polarizabilities, dispersion coefficients and repulsion parameters for individual molecules, and interaction energies between pairs of molecules using SAPT(DFT).&#039;&lt;br /&gt;
* [http://www-stone.ch.cam.ac.uk/programs.html CamCASP home]&lt;br /&gt;
* [[CamCASP/Programming]]&lt;br /&gt;
* [[CamCASP/Programming/5/example1]]&lt;br /&gt;
* [[CamCASP/Notes]]&lt;br /&gt;
* [[CamCASP/Bugs]]&lt;br /&gt;
* [[CamCASP/ToDo/diskIO]]&lt;br /&gt;
* [[CamCASP/ToDo/Memory]]&lt;br /&gt;
* [[CamCASP/CodeExamples/DirectAccess]]&lt;br /&gt;
&lt;br /&gt;
=== [[CPMD]] ===&lt;br /&gt;
Implementation of DFT for &#039;&#039;ab-initio&#039;&#039; molecular dynamics.&lt;br /&gt;
* [http://www.cpmd.org/ Home Page]&lt;br /&gt;
* [[CPMDInput]]&lt;br /&gt;
&lt;br /&gt;
=== [[CHARMM]] ===&lt;br /&gt;
Molecular dynamics simulation program and associated force fields.&lt;br /&gt;
* [https://www.charmm.org/charmm/?CFID=65f7b3aa-8037-452a-bcd1-7583dd83a087&amp;amp;CFTOKEN=0 CHARMM]&lt;br /&gt;
* [[Generating pdb, crd and psf for a peptide sequence]]&lt;br /&gt;
* [[Converting between &#039;.crd&#039; and &#039;.pdb&#039;]]&lt;br /&gt;
* [[Calculating energy of a conformation]]&lt;br /&gt;
* [[Calculating molecular properties]]&lt;br /&gt;
* [[Calculating order parameters]]&lt;br /&gt;
* [[CAMSHIFT]]&lt;br /&gt;
* [[Setting up (CHARMM)]] - step by step guide to prepare and then symmetrise a simple (protein-only) system&lt;br /&gt;
* [[If you need to change the number of atoms (e.g. making a united-atom charmm19 .crd file, or if atoms are missing)]]&lt;br /&gt;
* [[Performing a normal mode analysis of a biomolecule using OPTIM (AMBER and CHARMM)]]&lt;br /&gt;
* [[Minimizing a structure using OPTIM and CHARMM]]&lt;br /&gt;
* [[Alternatively, making the initial path with PATHSAMPLE itself (CHARMM)]]&lt;br /&gt;
* [[Expanding the kinetic transition network with PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Finding an initial path with OPTIM and starting up PATHSAMPLE (CHARMM)]]&lt;br /&gt;
* [[Pathsampling short paths (CHARMM)]]&lt;br /&gt;
&lt;br /&gt;
=== [[disconnectionDPS]] ===&lt;br /&gt;
Produces disconnectivity graphs from min.data and ts.data files. This is included in the Wales group public tarball.&lt;br /&gt;
* [[Constructing Free Energy Disconnectivity Graphs]]&lt;br /&gt;
&lt;br /&gt;
=== [[DMACRYS]] ===&lt;br /&gt;
Package which models crystals of rigid molecules.&lt;br /&gt;
* [http://www.chem.ucl.ac.uk/cposs/dmacrys/index.html Home Page]&lt;br /&gt;
* [[DMACRYS interface]]&lt;br /&gt;
* [[DMAGMIN setup]]&lt;br /&gt;
* [[PYGMIN &amp;amp; DMACRYS]]&lt;br /&gt;
&lt;br /&gt;
=== [[GAMESS]] ===&lt;br /&gt;
General &#039;&#039;ab initio&#039;&#039; quantum chemistry package.&lt;br /&gt;
* [https://www.msg.chem.iastate.edu/gamess/ GAMESS]&lt;br /&gt;
&lt;br /&gt;
=== [[Gaussian]] ===&lt;br /&gt;
General purpose package for computational chemistry calculations.&lt;br /&gt;
* [[Running an Gaussian03 interfaced OPTIM job]]&lt;br /&gt;
&lt;br /&gt;
=== [[gnuplot]] ===&lt;br /&gt;
Open source graphing program.&lt;br /&gt;
* [http://www.gnuplot.info/ gnuplot]&lt;br /&gt;
* [[Plotting a quick histogram in gnuplot using the raw data]]&lt;br /&gt;
* [[Plotting data in real time]]&lt;br /&gt;
* [[Linear and non-linear regression in gnuplot]]&lt;br /&gt;
&lt;br /&gt;
=== [[GROMACS]] ===&lt;br /&gt;
Molecular dynamics package.&lt;br /&gt;
* [[Installing GROMACS on Clust]]&lt;br /&gt;
* [http://www.mdtutorials.com/gmx/ External tutorials]&lt;br /&gt;
* [http://www.gromacs.org/Documentation/Tutorials More external tutorials]&lt;br /&gt;
&lt;br /&gt;
=== [[HiRE-RNA]] ===&lt;br /&gt;
High-res course-grained energy model for RNA.&lt;br /&gt;
* [https://pubs.acs.org/doi/10.1021/jp102497y Explanatory Paper]&lt;br /&gt;
&lt;br /&gt;
=== [[latex2html]] ===&lt;br /&gt;
Script which converts latex documents into HTML pages.&lt;br /&gt;
* [https://www.latex2html.org/ Get script here]&lt;br /&gt;
&lt;br /&gt;
=== [[MMTSB-toolset]] ===&lt;br /&gt;
Group of perl scripts which can be used to setup and run energy minimization, structural analysis and MD with CHARMM or AMBER.&lt;br /&gt;
* [http://feig.bch.msu.edu/mmtsb/Main_Page Documentation]&lt;br /&gt;
* [http://www.mmtsb.org/workshops/mmtsb-ctbp_2006/Tutorials/WorkshopTutorials_2006.html External tutorials]&lt;br /&gt;
* [[Installing and setting up the MMTSB toolset]]&lt;br /&gt;
* [[REX (Replica EXchange MD) with the MMTSB-toolset]]&lt;br /&gt;
&lt;br /&gt;
=== [[Simulations using OPEP | OPEP]] ===&lt;br /&gt;
OPEP is a coarse-grained force field providing a potential for proteins and RNA.&lt;br /&gt;
* [http://opep.galaxy.ibpc.fr/ OPEP file generator here]&lt;br /&gt;
* [[Biomolecules in the energy landscape framework]]&lt;br /&gt;
&lt;br /&gt;
=== [[pgprof]] === &lt;br /&gt;
Profiler for portland-compiled codes&lt;br /&gt;
* [[Portland compiler fails trying to allocate an unexpectedly large amount of memory: issue with large arrays]]&lt;br /&gt;
&lt;br /&gt;
=== [[Pymol]] ===&lt;br /&gt;
Molecular visualisation program.&lt;br /&gt;
* [https://pymol.org/2/ PyMOL]&lt;br /&gt;
* [https://pymolwiki.org/index.php/Main_Page PyMOL Community Wiki]&lt;br /&gt;
* [[loading AMBER prmtop and inpcrd files into Pymol]]&lt;br /&gt;
* [[producing sexy ray-traced images]]&lt;br /&gt;
* [[advanced colouring]]&lt;br /&gt;
* [[Installing python modules]]&lt;br /&gt;
* [[PYGMIN &amp;amp; DMACRYS]]&lt;br /&gt;
* [[path2pdb.py]] - A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.pdb&#039;&#039; - you can easy visualize your path in VMD :)&lt;br /&gt;
* [[extractedmin2pdb.py]]: A python program to convert &#039;&#039;exctractedmin&#039;&#039; to PDB format&lt;br /&gt;
=== [[VASP]] ===&lt;br /&gt;
OPTIM has an interface to VASP, which is installed on CSD3. In collaboration with Bora Karasulu the interface has been updated to use VASP format POSCAR input files for both single- and double-ended optimisations and path searches. The OPTIM odata file requires a line like&lt;br /&gt;
&lt;br /&gt;
VASP &#039;mpirun -ppn 16 -np 16 /home/bk393/APPS/vasp.5.4.4/with-VTST/bin/vasp_std &amp;gt; vasp.out&#039;&lt;br /&gt;
&lt;br /&gt;
POSCAR files can be visualised using ase, the Atomic Simulation Environment, which can be accessed on volkhan via&lt;br /&gt;
&lt;br /&gt;
module load anaconda/python3/5.3.0 &lt;br /&gt;
&lt;br /&gt;
pip install ase --user&lt;br /&gt;
&lt;br /&gt;
ase-gui POSCAR1.vasp &amp;amp;&lt;br /&gt;
&lt;br /&gt;
which assumes that ~/.input/bin is in your $PATH environment variable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== [[VMD]] ===&lt;br /&gt;
Molecular visualisation program.&lt;br /&gt;
* [http://www.ks.uiuc.edu/Research/vmd/current/ug/ug.html Documentation]&lt;br /&gt;
* [http://www.ks.uiuc.edu/Training/Tutorials/vmd/tutorial-html/index.html External tutorials]&lt;br /&gt;
* [[using VMD to display and manipulate &#039;.pdb&#039; files]]&lt;br /&gt;
* [[loading coordinate files into VMD with the help of an AMBER topology file]] e.g. to visualise the results of a GMIN run using AMBER9&lt;br /&gt;
* [[visualising normal modes using VMD and OPTIM]]&lt;br /&gt;
* [[path2pdb.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.pdb&#039;&#039; - you can easy visualize your path in VMD :)&lt;br /&gt;
* [[path2xyz.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.xyz&#039;&#039;&lt;br /&gt;
* [[extractedmin2pdb.py]]: A python program to convert &#039;&#039;exctractedmin&#039;&#039; to PDB format&lt;br /&gt;
* [[Useful .vmdrc file]]&lt;br /&gt;
* [[plotGMINms.tcl]]: a tcl script for plotting ellipsoids in VMD.&lt;br /&gt;
* [[VMD script to annotate each frame of a trajectory]]&lt;br /&gt;
&lt;br /&gt;
=== [[xfig]] ===&lt;br /&gt;
Open source vector graphics editor&lt;br /&gt;
* [https://ctan.org/tex-archive/support/epstopdf/ Convert eps to pdf]&lt;br /&gt;
&lt;br /&gt;
=== [[Xmakemol]] ===&lt;br /&gt;
Program for visualising atomic and molecular systems.&lt;br /&gt;
* [https://www.nongnu.org/xmakemol/ XMakemol]&lt;br /&gt;
&lt;br /&gt;
=== [[xmgrace]] ===&lt;br /&gt;
2D plotting tool.&lt;br /&gt;
* [http://exciting-code.org/xmgrace-quickstart Xmgrace]&lt;br /&gt;
&lt;br /&gt;
== Theoretical/Mathematical Notes ==&lt;br /&gt;
&lt;br /&gt;
* [[Density of states and thermodynamics from energy distributions at different temperatures]]&lt;br /&gt;
* [[Ellipsoid.model]]&lt;br /&gt;
* [[Ellipsoid.model.xyz]]&lt;br /&gt;
* [[Ellipsoid.xyz]]&lt;br /&gt;
* [[Gencoords]]&lt;br /&gt;
* [[GenCoords]]&lt;br /&gt;
* [[GenCoords Models]]&lt;br /&gt;
* [[Rotamer moves in AMBER]]&lt;br /&gt;
* [[Thomson problem in OPTIM]]&lt;br /&gt;
&lt;br /&gt;
=== Angle-axis notes ===&lt;br /&gt;
&lt;br /&gt;
* [[Angle-axis framework]]&lt;br /&gt;
* [[Computing normal modes in angle-axis]]&lt;br /&gt;
&lt;br /&gt;
=== Rigid Bodies ===&lt;br /&gt;
&lt;br /&gt;
* [[Automatic Rigid Body Grouping]]&lt;br /&gt;
* [[Rigid body input files for proteins using genrigid-input.py]]&lt;br /&gt;
* [[Local Rigid Body Framework]]&lt;br /&gt;
* [[Local rigid body in OPTIM]]&lt;br /&gt;
&lt;br /&gt;
== Useful Scripts ==&lt;br /&gt;
* [[perm-prmtop.py]]: A python program that converts an AMBER9 topology file into one with a symmetrised potential with respect to exchange (updated for AMBER12 and ff14SB).&lt;br /&gt;
* [[perm-pdb.py]]: A python program that creates a &#039;&#039;perm.allow&#039;&#039; file for use with [[OPTIM]] and [[PATHSAMPLE]].&lt;br /&gt;
* [[path2pdb.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.pdb&#039;&#039; - you can easy visualize your path in VMD :)&lt;br /&gt;
* [[path2xyz.py]]: A python program to convert &#039;&#039;path.info&#039;&#039; to &#039;&#039;path_all.xyz&#039;&#039;&lt;br /&gt;
* [[dijkstra_test.py]]: A python script to test whether the information in pairlist and ts.data connects the A and B set. (If not, PATHSAMPLE will not work without actually exiting.)&lt;br /&gt;
* [[extractedmin2pdb.py]]: A python program to convert &#039;&#039;exctractedmin&#039;&#039; to PDB format&lt;br /&gt;
* [[colourdiscon.py]]: A python program for sorting input for disconnectivity graphs&lt;br /&gt;
* [[pdb_to_movie.py]]: A python program to create an AMH movieseg file from a PDB file&lt;br /&gt;
* [[makerestart]]: A bash script to automatically set up a GMIN restart run&lt;br /&gt;
* [[progress]] A bash script to tell you the % completion of a GMIN job and give an estimated time remaining&lt;br /&gt;
* [[recommended bash aliases]]&lt;br /&gt;
* [[David&#039;s .inputrc file]]&lt;br /&gt;
* [[Useful .vmdrc file]]&lt;br /&gt;
* [[Density of states and thermodynamics from energy distributions at different temperatures]]&lt;br /&gt;
* [[GenCoords]]: A fortran program to generate coarse grain building blocks and initial coords using a set of geometric models.&lt;br /&gt;
* [[plotGMINms.tcl]]: a tcl script for plotting ellipsoids in VMD.&lt;br /&gt;
See also the SCRIPTS/ directory in the SVN repository!&lt;br /&gt;
* [[Computing CHARMM FF energy using GMIN, MMTSB and CHARMM]] - Computes the Charmm FF energy of the same structure. Useful for cross-validating force field settings in GMIN data file, CHARMM input file and MMTSB options.&lt;br /&gt;
* [[Automatic Rigid Body Grouping]]&lt;br /&gt;
* [[ElaborateDiff]]&lt;br /&gt;
* [[Parameter-scanning script]]&lt;br /&gt;
* [[Pdb to movie.py]]&lt;br /&gt;
* [[VMD script to annotate each frame of a trajectory]]&lt;br /&gt;
&lt;br /&gt;
== Useful links ==&lt;br /&gt;
* [http://www.ch.cam.ac.uk/computing/theory-compute-clusters The Theory Compute Clusters support page]. Contains useful cluster specific information, including example job submission scripts.&lt;br /&gt;
&lt;br /&gt;
* A useful website which contains AMBER (GAFF) and OPLS parameters for small molecules. http://virtualchemistry.org/gmld.php . This could save us lot of time while trying to derive parameters on our own. If you are lucky, the molecule of your interest may already be there in the existing database. The topology files are in GROMACS format but possibly can be converted into AMBER parameter files. (script anyone ?)&lt;br /&gt;
&lt;br /&gt;
* The moving-domain QM/MM method developed by Victor Batista&#039;s group http://gascon.chem.uconn.edu/software. This approach can be used in the derivation of charges for large proteins and nucleic acids, where a full-fledged ONIOM based calculation is comptutationally prohibitive. It has been applied to systems like the Gramicidin ion channel and Photosystem II.&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
* [[Animated GIF on the group website]]&lt;br /&gt;
* [[Backup strategy]]&lt;br /&gt;
* [[Chain crossing]]&lt;br /&gt;
* [[Computer Office services]]&lt;br /&gt;
* [[Computing values only once]]&lt;br /&gt;
* [[Decoding heat capacity curves]]&lt;br /&gt;
* [[Differences from Clust]]&lt;br /&gt;
* [[Fixing thunderbird links]]&lt;br /&gt;
* [[If you need to change the number of atoms (e.g. making a united-atom charmm19 .crd file, or if atoms are missing)]]&lt;br /&gt;
* [[Intel Trace Analyzer and Collector]]&lt;br /&gt;
* [[LDAP plans]]&lt;br /&gt;
* [[Lapack compilation]]&lt;br /&gt;
* [[Mek-quake Queueing system]]&lt;br /&gt;
* [[Mek-quake initial setup notes]]&lt;br /&gt;
* [[New mek-quake]]&lt;br /&gt;
* [[Maui compilation]]&lt;br /&gt;
* [[Torque and Maui]]&lt;br /&gt;
* [[Mercurial]]&lt;br /&gt;
* [[Migrating to the new SVN server]]&lt;br /&gt;
* [[NECI Parallelization]]&lt;br /&gt;
* [[Optimization tricks]]&lt;br /&gt;
* [[Other IT stuff]]&lt;br /&gt;
* [[Porfuncs Documentation]]&lt;br /&gt;
* [[Progress]]&lt;br /&gt;
* [[Proposed changes to backup and archiving]]&lt;br /&gt;
* [[Rama upgrade]]&lt;br /&gt;
* [[Remastering Knoppix]]&lt;br /&gt;
* [[See unpacked nodes]]&lt;br /&gt;
* [[Tardis scheduling policy]]&lt;br /&gt;
* [[Zippo Sicortex machine]]&lt;br /&gt;
* [[Beginner&#039;s guide to working in Wales group]]&lt;br /&gt;
&lt;br /&gt;
== Useful linux stuff ==&lt;br /&gt;
&lt;br /&gt;
===Basics===&lt;br /&gt;
* [[basic linux commands everyone should know!]]&lt;br /&gt;
* [[piping and redirecting output from one command or file to another]] - how to save yourself hours!&lt;br /&gt;
* [[bash loop tricks]]&lt;br /&gt;
* [[bash history searching]]&lt;br /&gt;
&lt;br /&gt;
===Remote access===&lt;br /&gt;
* [[setting up aliases to quickly log you in to a different machine]]&lt;br /&gt;
* [[transfering files to and from your workstation]] -using &#039;&#039;scp&#039;&#039; or &#039;&#039;rsync&#039;&#039;&lt;br /&gt;
* [[using &#039;ssh-keygen&#039; to automatically log you into clusters from your workstation]] (no more typing in your password!)&lt;br /&gt;
* [[mounting sharedscratch locally]]&lt;br /&gt;
&lt;br /&gt;
===Find and replace===&lt;br /&gt;
* [[short &#039;sed&#039; examples]]&lt;br /&gt;
* [[quick guide to awk]]&lt;br /&gt;
* [[short &#039;awk&#039; examples]]&lt;br /&gt;
&lt;br /&gt;
===File manipulation===&lt;br /&gt;
* [[sorting a file by multiple columns]]&lt;br /&gt;
* [[using tar and gzip to compress/uncompress files | using tar and bzip2 to compress/uncompress files]]&lt;br /&gt;
* [[conversion between different data file formats]] -&#039;almost one-line&#039; scripts&lt;br /&gt;
* [[conversion between different image file formats]] - the &#039;&#039;convert&#039;&#039; command&lt;br /&gt;
* [[removing an excessive number of files from a directory - when &#039;rm&#039; just isn&#039;t enough]]&lt;br /&gt;
&lt;br /&gt;
===Cluster queues===&lt;br /&gt;
* [[submitting jobs, interactively or to a cluster queue system]]&lt;br /&gt;
* [[identifying job on a node]] - if you need to kill only one of few running jobs&lt;br /&gt;
* [[getting started with SLURM]]&lt;br /&gt;
* [[a guide to using SLURM to run PATHSAMPLE]]&lt;br /&gt;
* [[a guide to using SLURM to run GPU jobs on pat]]&lt;br /&gt;
* [[managing interactive jobs on cluster]]&lt;br /&gt;
&lt;br /&gt;
===Miscellaneous/uncategorised===&lt;br /&gt;
* [[installing packages on your managed CUC3 workstation]]&lt;br /&gt;
* [[running programs in the background]] - so you can use your shell for other things at the same time&lt;br /&gt;
* [[finding bugs in latex documents that will not compile]]&lt;br /&gt;
* [[printing files from the command line using &#039;lpr&#039;]]&lt;br /&gt;
* [[uploading non image files to the wiki]]&lt;br /&gt;
&lt;br /&gt;
== Compiler Flags ==&lt;br /&gt;
&lt;br /&gt;
* [[Compiler Flags]]&lt;br /&gt;
* [[Blacklisting Compilers]]&lt;br /&gt;
* [[Lapack compilation]]&lt;br /&gt;
* [[Pdb to movie.py]]&lt;br /&gt;
* [[Portland compiler fails trying to allocate an unexpectedly large amount of memory: issue with large arrays]]&lt;br /&gt;
&lt;br /&gt;
== SuSE ==&lt;br /&gt;
&lt;br /&gt;
* [[Upgrading destiny]]&lt;br /&gt;
* [[Upgrading sword]]&lt;br /&gt;
* [[SuSE 10.1 workstation image]]&lt;br /&gt;
* [[SuSE 10.2 workstation image]]&lt;br /&gt;
* [[SuSE 10.3 workstation image]]&lt;br /&gt;
* [[SuSE 11.1]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:adk44|adk44]] 17.00, 9 May 2019 (BST)&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
	<entry>
		<id>https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Getting_started_with_SLURM&amp;diff=1599</id>
		<title>Getting started with SLURM</title>
		<link rel="alternate" type="text/html" href="https://wikis.ch.cam.ac.uk/ro-walesdocs/wiki/index.php?title=Getting_started_with_SLURM&amp;diff=1599"/>
		<updated>2020-05-26T13:11:43Z</updated>

		<summary type="html">&lt;p&gt;Jwrm2: Created page with basic information about SLURM.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For running computationally expensive tasks for long periods of time, you will want to create a job and run it on a cluster. This page is intended to teach you everything required to run your first job on a SLURM CPU cluster (sinister, volkhan). For convenience, we will refer primarily to sinister, but the information is transferrable to other SLURM clusters. This page does not contain information about PBS (dexter). If you are running GPU (pat) jobs, you will need additional information from [[A guide to using SLURM to run GPU jobs on pat | here]].&lt;br /&gt;
&lt;br /&gt;
==Basic terminology==&lt;br /&gt;
&lt;br /&gt;
A cluster is a large computer that has many processors. The processors are grouped into nodes, which operate semi-independently of each other. Each node has it&#039;s own disk (accessed at /scratch/) and memory, but is capable of communicating with other nodes through a network. When you login to sinister with SSH, you are logged into the head node. This is a special node designed for interacting with users. The other nodes are compute nodes, designed for running long and intensive tasks. SLURM (Simple Linux Utility for Resource Management), now officially called the Slurm Workload Manager, is a programme that manages the compute nodes, allocating resources, starting and ending jobs, and managing the queue. To get the compute nodes to do anything, you need to ask through SLURM.&lt;br /&gt;
&lt;br /&gt;
==How to not be anti-social==&lt;br /&gt;
&lt;br /&gt;
When you are using sinister, the most important thing to be aware of is that other people are using it too. You need to be careful to not act in a way that impedes other users from getting on with their work. Primarily this means not excessively using the head node, as if you do other users will get a very slow response time on their SSH and will not be able to operate. There are some specific things to avoid.&lt;br /&gt;
&lt;br /&gt;
*Do not run long expensive tasks on the head node: that is what the compute nodes are for. Anything longer than a few minutes should not be run on the head node. For a short expensive task (like compiling GMIN), prefix your command with &#039;nice&#039;, which tells the operating system to give your process a lower priority, meaning any simple commands other people might be running are not slowed down. You are not likely to notice a significant impact on the speed of your process by doing this.&lt;br /&gt;
&lt;br /&gt;
  $ nice make&lt;br /&gt;
&lt;br /&gt;
*Do not rapidly copy a lot of data over the network. Although the nodes are networked together and moving data between them is a simple process (using NFS, the Network File System), it is relatively slow and is computationally expensive. If you constantly move data over the NFS, for example by writing a verbose log file, other users will notice. This is most likely to be an issue when writing to the directory /sharedscratch/, which is a large working space partition accessible over the network from any partition. Each node has its own space, accessed at /scratch/ on the node, or through /nodescratch/ from the head node. Best practices to avoid this problem are detailed below, but it is mentioned here due to its great importance.&lt;br /&gt;
&lt;br /&gt;
*Be realistic about the requirements for your job. The cluster is a shared resource that is not infinite. To make the most efficient use of the resource, do not do things like request 32 cores for a job that can only make use of 4, or request a time limit of 1 week for a job that will only take 1 hour. The better the information you give to the queuing system, the better it can serve you.&lt;br /&gt;
&lt;br /&gt;
==Submitting a job==&lt;br /&gt;
&lt;br /&gt;
To submit a job, you create a job submission script, here we&#039;ll call it submit.sh, and then run&lt;br /&gt;
&lt;br /&gt;
  $ sbatch submit.sh&lt;br /&gt;
&lt;br /&gt;
which tells SLURM to execute the contents of your submission script. When you do this, SLURM will first look through any information at the top of the job script for configuration instructions like the job time limit. Then it will place your job into a queue. When the necessary resources become available, any commands in your submission script will be executed in sequence on a compute node. Let&#039;s have a look at a simple submission script for running GMIN.&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J GMIN_LJ38&lt;br /&gt;
  #SBATCH --time=1:00:00&lt;br /&gt;
  #SBATCH -n1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/data $SLURM_SUBMIT_DIR/coords $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/bin/GMIN &amp;gt; logfile&lt;br /&gt;
  &lt;br /&gt;
  cp -p lowest logfile $SLURM_SUBMIT_DIR &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR&lt;br /&gt;
&lt;br /&gt;
We&#039;ll go through this line by line. The first line (affectionately known as the &#039;shebang&#039;) tells SLURM what shell to use to interpret the commands. You don&#039;t have to use Bash, but it&#039;s what most people are used to, so it&#039;s recommended if you want anyone else to be able to help you.&lt;br /&gt;
&lt;br /&gt;
Next we have a series of configuration commands for SLURM. Each of these starts with #SBATCH and they are ignored by Bash. Some of the most useful are:&lt;br /&gt;
&lt;br /&gt;
* -J &amp;lt;name&amp;gt;  The name of the job, that will show up in diagnostic information. Make your life easier by choosing a suitably descriptive one.&lt;br /&gt;
* --time=hh:mm:ss The maximum amount of time your job will run for. If this time limit is reached and the job hasn&#039;t finished, SLURM will kill it. It is in yours and everyone else&#039;s interest to make this a fairly accurate estimate of how long the job will actually take (plus a little bit).&lt;br /&gt;
* --ntasks=&amp;lt;number&amp;gt; The number of processors your job requires.&lt;br /&gt;
* --nodes=&amp;lt;number&amp;gt; The number of nodes your job requires.&lt;br /&gt;
* --mem=&amp;lt;value&amp;gt; The amount of memory your job needs. The default is often fine.&lt;br /&gt;
&lt;br /&gt;
Consult the SLURM documentation [https://slurm.schedmd.com/sbatch.html] for a full list. Here, we request one processor, for a maximum time of 1 hour, and we set the name to &#039;GMIN_LJ38&#039;.&lt;br /&gt;
&lt;br /&gt;
The remaining commands are executed by Bash once the job has begun. First we write out some diagnostic information: the ID of the job and which compute node it is running on. This is written to a file slurm-&amp;lt;job_ID&amp;gt;.out in the directory we run sbatch from, for example&lt;br /&gt;
&lt;br /&gt;
  $ cat slurm-214233.out&lt;br /&gt;
  Starting job 214233&lt;br /&gt;
  compute-0-17.local&lt;br /&gt;
&lt;br /&gt;
The first line is a useful check that the job actually began. Knowing which node your job ran on can be useful if it terminates early/unexpectedly.&lt;br /&gt;
&lt;br /&gt;
The next section of the submission script is about reducing the NFS load. Instead of running the job on /sharedscratch/, which the node accesses over the NFS, we create a directory in the node&#039;s own /scratch/ space. Change &#039;jwrm2&#039; to your own username. We copy only the files GMIN needs in order to run, then change to the new directory. $SLURM_SUBMIT_DIR is a variable holding the directory from whcih sbatch was run.&lt;br /&gt;
&lt;br /&gt;
Next we actually run the programme. We redirect the GMIN output to a log file. If you do not do this redirection, output will instead go to the slurm-&amp;lt;job_ID&amp;gt;.out file, which most likely resides on /sharedscratch/.&lt;br /&gt;
&lt;br /&gt;
Finally, we have clean up actions to be run after GMIN has finished. We copy back only the data we are interested in to the directory from which sbatch was run, then delete the temporary directory we created on the nodescratch. Note the &#039;&amp;amp;&amp;amp;&#039; syntax, which means &#039;run the command after the &amp;amp;&amp;amp; only if the command before the &amp;amp;&amp;amp; was successful&#039;. In this case, it means that the temporary directory will not be deleted if we couldn&#039;t copy those files back.&lt;br /&gt;
&lt;br /&gt;
==The queuing system==&lt;br /&gt;
&lt;br /&gt;
When you submit your job with sbatch, it may not be run instantly. It is quite possible that the the resources your job needs are currently being used by someone else. Your job enters the queue. You can see the queue by typing&lt;br /&gt;
&lt;br /&gt;
  $ squeue&lt;br /&gt;
               JOBID PARTITION                                               NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
              214233   CLUSTER                                          GMIN_LJ38    jwrm2 PD       0:00      1 (Resources)&lt;br /&gt;
              214207   CLUSTER                                              GLP-1    kr366  R      29:31      2 compute-0-[22-23]&lt;br /&gt;
              214112   CLUSTER                                    pentamer_1_1292    ld506  R 1-02:03:44      1 compute-0-12&lt;br /&gt;
&lt;br /&gt;
There is a lot of information here. The first column gives the ID of the job. The next column is not usually relevant. Then we see the name of the job (assigned with -J in the submission script) and the user who submitted the job. The ST column tells you the current status of the job: &#039;PD&#039; means &#039;pending&#039;, ie. the job is waiting to run, but is not yet running; &#039;R&#039; means &#039;running&#039;. We also have the time the job has been running for, the number of nodes the job is using and which they are. If the job is not running, the final column may display a reason. If it shows (Resources), then your job will run as soon as the necessary resources are available. If it instead shows (Priority), then there is another waiting job in the queue that will be run before yours. If you only want to see information about your jobs (or any other user&#039;s), you can use the -u option:&lt;br /&gt;
&lt;br /&gt;
  $ squeue -u jwrm2&lt;br /&gt;
&lt;br /&gt;
will only show the jobs submitted by the user jwrm2.&lt;br /&gt;
&lt;br /&gt;
How does SLURM decide which jobs to run? Principally, it works out a user&#039;s priority by a fairshare system: the more compute time you have recently used, the lower your priority will be. You can see everyone&#039;s fairshare values by looking at the final column of the output of&lt;br /&gt;
&lt;br /&gt;
  $ sshare -a&lt;br /&gt;
&lt;br /&gt;
Higher numbers mean a higher priority for that user. However, SLURM will also try to fit smaller jobs into gaps. If there is a 12 node job waiting from a user with a very high priority, but only one node is currently available, a short one node job from a user with low priority may be able to fit in. Therefore it is in your interest to make realistic estimates of the resources your job needs: it may end up running sooner.&lt;br /&gt;
&lt;br /&gt;
==Oops, I just submitted the wrong job==&lt;br /&gt;
&lt;br /&gt;
You can abort a job when it is waiting to run or when it is running. Find the job ID, either by looking at squeue or the output file in the submission directory. Let&#039;s say it was 214233:&lt;br /&gt;
&lt;br /&gt;
  $ scancel 214233&lt;br /&gt;
&lt;br /&gt;
will immediately kill the job.&lt;br /&gt;
&lt;br /&gt;
==Running PATHSAMPLE with SLURM==&lt;br /&gt;
&lt;br /&gt;
PATHSAMPLE runs a little differently from standard GMIN: it launches new OPTIM jobs and sends them to the other processors available. This is pretty much taken care of if you include &#039;SLURM&#039; in the pathdata file, but there are a couple of extra considerations. Firstly, PATHSAMPLE needs a nodes.info file with information about the available processors. Generate this file at the start of you submission script with:&lt;br /&gt;
&lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
&lt;br /&gt;
Note the use of srun here. It means: run this command on every one of the available processors.&lt;br /&gt;
&lt;br /&gt;
Secondly, we need to decide whether PATHSAMPLE itself will be run from /sharedscratch/ (not the OPTIM jobs, PATHSAMPLE will always use /nodescratch/ for those). Running PATHSAMPLE from /sharedscratch/ is simpler and it means that if the job terminates before PATHSAMPLE completes all the requested cycles, the database on /sharedscratch/ will be in the most current state. Here is an example PATHSAMPLE script that does this&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH --time=20:0:0&lt;br /&gt;
  #SBATCH --job-name=PATHSAMPLE_LJ38&lt;br /&gt;
  #SBATCH --ntasks=16&lt;br /&gt;
  &lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm/bin/PATHSAMPLE &amp;gt; logfile&lt;br /&gt;
&lt;br /&gt;
We run PATHSAMPLE for 20 hours on 16 cores. SLURM is free to assign those cores over multiple nodes as it sees fit. Note there is no creation of a temporary directory on /scratch/, PATHSAMPLE access the database stored in /sharedscratch/. Whenever an OPTIM job is created, PATHSAMPLE creates a temporary directory on /scratch/, copies the files required for OPTIM to run, launches OPTIM with srun, waits for OPTIM to finish, copies the files back and adds new stationary points to the database, then deletes the temporary directory. That is all taken care of for you. Because this approach involves writing to /sharedscratch/, it is only appropriate if each OPTIM job takes a while to run (more than a few minutes) and if the amount of data required for each OPTIM job is small. If either of those conditions is violated, users may notice a slowdown on the head node and be annoyed with you. In that case a different approach is required.&lt;br /&gt;
&lt;br /&gt;
PATHSAMPLE can be run from /nodescratch/. This method reduces the NFS load, but is slightly more complicated and if the job terminates early, you will need to get your expanded database manually (see [[Getting started with SLURM#My job got cancelled, where are my files? | here]]). Here is an example PATHSAMPLE script that does this&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J PATHSAMPLE_LJ38&lt;br /&gt;
  #SBATCH --time=20:0:0&lt;br /&gt;
  #SBATCH --ntask=4&lt;br /&gt;
  #SBATCH --nodes=1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/pathdata $SLURM_SUBMIT_DIR/min.data $SLURM_SUBMIT_DIR/ts.data $SLURM_SUBMIT_DIR/points.min $SLURM_SUBMIT_DIR/points.ts $SLURM_SUBMIT_DIR/min.A $SLURM_SUBMIT_DIR/min.B $SLURM_SUBMIT_DIR/odata.connect $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  echo $SLURM_NTASKS &amp;gt; nodes.info&lt;br /&gt;
  srun hostname &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  echo $USER &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  pwd &amp;gt;&amp;gt; nodes.info&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/svn/PATHSAMPLE/builds/gfortran/PATHSAMPLE &amp;gt; logfile&lt;br /&gt;
  &lt;br /&gt;
  cp min.data ts.data points.min points.ts min.A min.B logfile $SLURM_SUBMIT_DIR/ &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR/&lt;br /&gt;
&lt;br /&gt;
We run for 20 hours on 4 cores. Since we are worried about the amount of data we&#039;re copying around, it makes sense to request these on the same node. We create a temporary directory on the node&#039;s /scratch/ space and copy the whole PATHSAMPLE database to it. Then we generate the nodes.info file and we&#039;re ready to run PATHSAMPLE itself. At the end, we copy the whole database back to /sharedscratch/ and delete the temporary directory if successful. This solution is not perfect, as we still have to copy the whole database over the NFS at the start and the end, but if each OPTIM job needs a lot of writing, or writes data very rapdily, it may be preferable.&lt;br /&gt;
&lt;br /&gt;
==My job got cancelled, where are my files?==&lt;br /&gt;
&lt;br /&gt;
If your job has finished, it will no longer appear in the output of squeue. It may have successfully completed, or it might have run out of time (or memory, etc.). Look at the end of the slurm-&amp;lt;job_ID&amp;gt;.out file. If it shows&lt;br /&gt;
&lt;br /&gt;
  slurmstepd: *** JOB 214233 ON compute-0-36 CANCELLED AT 2020-05-18T10:45:16 DUE TO TIME LIMIT ***&lt;br /&gt;
&lt;br /&gt;
then your job ran out of time and was killed. Maybe this was a week long GMIN run that ran out of time 10 steps from the end. How annoying. Time to run it again from the beginning with a longer time limit, because there is no GMIN.dump file in the submission directory? Hardly... In our job submission script, we only deleted the temporary directory after the successful completion of the job. Therefore if the job did not successfully complete, the directory and its contents are still there. The information at the top of the slurm-&amp;lt;job_ID&amp;gt;.out file will help you find them. We created the temporary directory at&lt;br /&gt;
&lt;br /&gt;
  /scratch/jwrm2/214233&lt;br /&gt;
&lt;br /&gt;
To access this from the head node, we need to know what node it was created on. That&#039;s why we ran &#039;hostname&#039; at the start of the job. Let&#039;s say the output of that was&lt;br /&gt;
&lt;br /&gt;
  compute-0-17.local&lt;br /&gt;
&lt;br /&gt;
We can access our files at&lt;br /&gt;
&lt;br /&gt;
  /nodescratch/compute-0-17/jwrm2/214233&lt;br /&gt;
&lt;br /&gt;
Note that normal Bash tab completion of the directory name may not work here. That doesn&#039;t necessarily mean the directory doesn&#039;t exist, it&#039;s just a peculiarity of NFS automount.&lt;br /&gt;
&lt;br /&gt;
It would be polite to delete the temporary directory after recovering any files you need.&lt;br /&gt;
&lt;br /&gt;
==A smarter way to get your files==&lt;br /&gt;
&lt;br /&gt;
Although recovering files from /nodescratch/ is fine, if you&#039;ve every had 52 GMIN jobs terminate and needed to recover their GMIN.dump files for restarting, it gets a little tedious. Fortunately there is a better way, leveraging the signal mechanism of Linux. Here is an example:&lt;br /&gt;
&lt;br /&gt;
  #!/bin/bash&lt;br /&gt;
  #SBATCH -J GMIN_LJ38&lt;br /&gt;
  #SBATCH --time=5:00&lt;br /&gt;
  #SBATCH -n1&lt;br /&gt;
  #SBATCH --signal=B:USR1@120&lt;br /&gt;
  &lt;br /&gt;
  signal_handler()&lt;br /&gt;
  {&lt;br /&gt;
      # Timeout commands go here&lt;br /&gt;
      echo &amp;quot;Caught USR1 signal&amp;quot;&lt;br /&gt;
      cp GMIN.dump logfile $SLURM_SUBMIT_DIR&lt;br /&gt;
      exit&lt;br /&gt;
  }&lt;br /&gt;
  trap &#039;signal_handler&#039; USR1&lt;br /&gt;
  &lt;br /&gt;
  echo Starting job $SLURM_JOB_ID&lt;br /&gt;
  hostname&lt;br /&gt;
  &lt;br /&gt;
  TMP=/scratch/jwrm2/$SLURM_JOB_ID&lt;br /&gt;
  mkdir -p $TMP&lt;br /&gt;
  cp $SLURM_SUBMIT_DIR/data $SLURM_SUBMIT_DIR/coords $TMP/&lt;br /&gt;
  cd $TMP&lt;br /&gt;
  &lt;br /&gt;
  /home/jwrm2/bin/GMIN &amp;gt; logfile &amp;amp;&lt;br /&gt;
  wait&lt;br /&gt;
  &lt;br /&gt;
  cp -p lowest logfile $SLURM_SUBMIT_DIR &amp;amp;&amp;amp; rm -rf $TMP&lt;br /&gt;
  cd $SLURM_SUBMIT_DIR&lt;br /&gt;
&lt;br /&gt;
This script will run any commands enclosed in braces at &#039;# Timeout commands go here&#039;, 120 seconds before the job times out. It will terminate itself immediately after completing those commands, so you will not get a &#039;CANCELLED&#039; message in the slurm-&amp;lt;job_ID&amp;gt;.out file (but only because of the &#039;exit&#039;, otherwise it would continue execution after the &#039;wait&#039;, which is probably not what you want). You can use it to copy back recovery files like GMIN.dump, or the updated PATHSAMPLE database, before the job terminates. If 120 seconds is not enough time for your timeout commands, change the 120 in the line &#039;#SBATCH --signal=B:USR1@120&#039;. The temporary directory will not be deleted if the timeout is reached, although you could put &#039;rm -rf $TMP&#039; in the timeout section if you were really confident that you were grabbing everything you needed. You should occasionally go through /nodescratch/ and delete any leftover temporary directories that may be hanging around.&lt;br /&gt;
&lt;br /&gt;
===Theory===&lt;br /&gt;
&lt;br /&gt;
You don&#039;t need to understand how the above example works to use it, but we&#039;re all curious scientists, aren&#039;t we? The Linux kernel can communicate with a running process by sending it &#039;signals&#039;. Common ones include &#039;SIGTERM&#039; and &#039;SIGKILL&#039;. In fact, when your job reaches the time limit, it gets sent a &#039;SIGTERM&#039; signal, telling it to terminate. If the process has not set up anything specific to do on receiving a particular signal, the default action is to exit. However, most signals can have custom responses set up. An exception is &#039;SIGKILL&#039;, for which immediate termination cannot be overridden. &lt;br /&gt;
&lt;br /&gt;
The line &#039;#SBATCH --signal=B:USR1@120&#039; tells SLURM to please send the signal &#039;USR1&#039; (user specified signal number 1) to the job 120 seconds before reaching the time limit. &#039;USR1&#039; is not sent by any system processes, so we&#039;re free to use it as we wish. Next we create a Bash function, &#039;signal_handler()&#039;, with our sequence of commands. We tell the Bash script to jump to our function on receiving the &#039;USR1&#039; signal, overriding the default exit behaviour (trap &#039;signal_handler&#039; USR1).&lt;br /&gt;
&lt;br /&gt;
The final finicky bit is how we run our main programme. If we ran &#039;GMIN&#039;, the signal would get sent to GMIN, as the active process, rather than Bash. GMIN wouldn&#039;t know what to do with it, so would immediately exit. Not good. By running &#039;GMIN &amp;amp;&#039; instead, the signal goes to Bash. However, if we did just that, the job would quickly reach the end after launching GMIN, whcih would terminate the job and all it&#039;s children, including GMIN. Oops. By writing &#039;wait&#039;, we tell Bash to go into an &#039;interruptible sleep&#039;, meaning it will sit there not doing anything until it receives a signal. Therefore it is able to exceute the commands in the &#039;signal_handler()&#039; function on receiving the &#039;USR1&#039; signal. As a matter of interest, execution of the main script then resumes where it left off before the signal, but the wait has now been completed (it only waits for the first signal) and execution proceeds to the &#039;cp&#039; line. Putting &#039;exit&#039; at the end of the function means we don&#039;t junp back to after wait. We could have put another &#039;wait&#039; instead of &#039;exit&#039;, but that would only be useful if GMIN finished in the short period of time between completing the function and reaching the job time limit. Better to just save 2 minutes of CPU time by exiting immediately.&lt;br /&gt;
&lt;br /&gt;
How does our job finish normally, if we&#039;ve put it to sleep then? Well, when GMIN exits it sends, you guessed it... a signal, in this case &#039;SIGCHLD&#039;. That will wake up Bash from its wait and the script will proceed to completion.&lt;/div&gt;</summary>
		<author><name>Jwrm2</name></author>
	</entry>
</feed>