GFDL - Geophysical Fluid Dynamics Laboratory

Guide to git for FMS Users and Developers

This document provides a brief description of git and some specifics on how it is implemented for FMS.  A similar guide for CVS is also available.  For more details on git see the homepage, which contains a user reference and a full copy of the Pro Git book a list of tutorials and other help materials.  Graphical user interfaces (GUI) are available with git (git-gui, gitk) for both committing and local views of the repository logs.  The git repositories for GFDL are located on the lab’s gitlab instance.

Git is a source code management (SCM) system.  It maintains a record of all changes made to a project in a group of files called the repository.  The official master git repository is located on GFDL’s gitlab server. The fms user, a computer system user on the GFDL systems, acts as the super-user for all the git repositories.

As most users in the GFDL community are familiar with the Concurrent Version System (CVS), the information provided in this guide will leverage on the concepts of CVS.  However, it is important to understand the differences in git and CVS.

Git for CVS users

The largest difference between git and CVS is the repository layout.  In CVS files for a particular group of code (project) is managed with a set of CVS modules. A single CVS repository can have multiple modules.  With git, the repository is more like the CVS module.

Another difference is git does not support the checkout of a single file from the repository.  Git considers the repository as a single entity, and will grab every file during the clone/checkout.

Lastly, git is a distributed system.  Thus, each working directory is a full copy of the repository.  When the repository is “downloaded”, every file and every revision is “cloned” into the working directory.  This has the slight disadvantage in that modifications to the working directory are not mirrored back to the “official” master repository.  Pushing back changes is a separate step.

Tags and branches have similar meanings in git as they do in CVS.

Branch Creation Summary for FMS Developers

The FMS developers have been assigned to a group on the gitlab server.  If you have a GFDL account and wish to join the FMS developers group, please submit a help desk ticket

When checking in modifications to code, it is important to start from the correct version of the code.  For example, if you have modified tikal code, you should start from the “tikal” tag in your working repository.  If your change is to be included into the next software cycle, you should start with the current testing branch code.  If not, your modifications may not be accepted.  Note that the testing branch is used to test updates that will be included in the next city/patch release and should not be used for production runs.

Using git status and git log before and after each command below will help inform you how the repository changes after each command.  Click on the individual git commands for more details on the specific commands. Also running git <command> --help should display the on-line manual page.

To check in modified files on a new branch:

git checkout -b user/$user/<branch_name>

git add files

git commit

git push origin user/$user/<branch_name>
  1. Use git checkout -b to create and checkout a new branch starting from the current location.  The branch name should have the form user/$user/branch_name. See documentation on branch naming
    conventions
    .
  2. Add the file as a git tracked file, and place it on the index – a list of changes to be included in the next commit.
  3. Commit the change to the local git repository
  4. (Optional) Push changes back to the “origin” repository. This step is required to allow others to see and use the modifications.

To check in modified/new files on your existing branch:

git status

git add files

git commit

git push user/$user/<branch_name>
  1. Check the status to verify that you are on the correct branch (look for string “# On branch <Your_Branch>” and the file is listed as modified.
  2. Add the modified file to the index.
  3. Commit the change
  4. (Optional) Push changes back to the “origin” repository. This step is required to allow others to see and use the modifications.

To remove a file from the repository on a branch:

git rm files

git commit

git push user/$user/<branch_name>
  1. Use git rm to delete the file, and add it’s removal to the index.
  2. Commit the change to the local repository.
  3. (Optional) Push changes back to the “origin” repository. This step is required to allow others to see and use the modifications.

To add a revision tag to a file or directory:

git tag user/$user/<tag_name>

git push user/$user/<tag_name>
  1. Use git tag to place a tag on the current revision of the repository.  The name of the tag should have the form user/$user/<tag_name>
  2. (Optional) Push changes back to the “origin” repository. This step is required to allow others to see and use the tag.

To remove a revision tag from a file or directory:

git tag -d user/$user/<tag_name>

git push origin :refs/tags/<user/$user/<tag_name>
  1. Use git tag -d to delete the tag. NOTES:
    • This command will delete the named tag reference from the commit irregardless of the current state/commit of the working directory.
    • This command does not remove code versions from the repository, it simply removes the named tag reference from the commit.
  2. (Optional) Push changes back to the “origin” repository. This step is required to delete the tag on the remote git repository. Note: Not all users can delete tags on the gitlab server.

General Information and Formatting of git Commands:

git -help Display a brief help message listing the git options, and a list of the most commonly used commands.
git <command> -h List a brief help message on the usage of <command>.  For example, cvs clone -h will print a help message for the clone git command.
git <command> --help Display the man page for the <command>.  Note: The same man page can be displayed by running man git-<command>.  For example, git add -h and man git-add will both display the same man page.
git <command> [<files>] This is the general format for git commands.  Note: Some git commands will require a list of files (e.g. git add <files>) while other will work on the repository (e.g. git branch).  There is also a subset of commands that can either work on the repository, or a list of files (e.g. git checkout [<files>]).

Commands which do not modify the repository:

The following commands are for acquiring code from the FMS repository and inquiring as to the state of your local code compared with the state of the repository.

Clone Command:

git clone [-b <branch>] <repo>
Example: git clone -b siena_201309 git@gitlab.gfdl.noaa.gov:fms/sharedClone the repository located at
git@gitlab.gfdl.noaa.gov:fms/shared and checkout the “siena_201309”
named tag/branch.
Description:Clones the full repository located at <repo>, and optionally checkout a particular branch/tag. Please note, the git clone is more like CVS checkout in that collects revision information from a remote repository.  Git, unlike CVS, will always clone a full repository – all files, all revision.  Like CVS, if a particular branch/tag are not listed on the command line, then the HEAD (trunk in CVS) is left in the working directory. FMS Considerations:When asking for a particular tag, a warning stating that the working directory is in a “detached HEAD” state.  This is simply a warning to let you know that if changes are committed, then they will not be associated with any named branch.  It is suggested that all modification be placed on a branch. Thus run then command git checkout -b <branch_name> prior to committing any changes.

Checkout Command:

git fetch [<remote_name> [<branch>]]
Example: git fetch origin dev/masterFetch the changes for branch dev/master from remote origin.
Description:Since git is a distributed SCM, most of the commands run only affect the local repository.  Because of this, it is necessary to manually syncrozice the upstream (remote) modification into the local repository.  git fetch polls the upstream repository and downloads all new commits. These new commits are not applied to any of the local branches, but are available locally under the branch names <remote>/<branch>.  The git command git branch -r will list all remote branches. FMS Considerations:Fetching commit data does not update any local branches.  Before pushing any of your updates to the remote repository, verify that your local “tracking” branch is up-to-date with the remote branch.  Otherwise your push will not be accepted.

Status Command:

git status
Example: git statusShow the current status of the working directory.
Description:Shows the current state of the working directory.  git status shows three important pieces of information:

  1. The current branch
  2. The files placed on the index
  3. Any files that have modification that are not included in the index
FMS Considerations:None.

Diff Command:

git diff [--cached] [<file>]
git diff <commit> [<commit>] [<file>]
Example: git diff diag_manager/diag_manager.F90Display the difference between the current state of
diag_manager/diag_manager.F90 and the last revision
committed.
Description:Display the difference between files not on the index, and the last commit. Files place on the index are ignored unless the --cached option is used.  To compare files between different commits, list the <commit>s and then optionally the file(s) to compare. FMS Considerations:None.

Diff Command:

git log [<since>..<until>] [<file>]
Example: git log diag_manager/diag_manager.F90Display the commits where diag_manager/diag_manager.F90 was modified.
Description:Display the commit log (which includes the commit ID, author, date and commit message) for the full repository, or for a given file.  If a file is listed, then only the commit entries where the file was modified are displayed.  If a range of commits, done with the syntax <since>..<until>, is given then only commits in that range are displayed. FMS Considerations:None.

Commands which do modify the repository:

The following commands allow developers add files and modifications to the repository

Checkout Command:

git checkout [-b] <tag|branch|commit_hash>
git checkout [<tag|branch|commit_hash>] -- [<file>]
Example: git checkout siena_201309Checkout the “siena_201309” named tag/branch of the repository.
Description:Checks out a particular revision of the repository. If a file is listed, then git will get a particular version of the file and place in the current working directory. Useful to pull file modifications from a particular branch/tag and apply the modification without performing a merge. Note: If the -b option is given, the git -t checkout <branch> will create a new branch. FMS Considerations:When asking for a particular tag, a warning stating that the working directory is in a “detached HEAD” state.  This is simply a warning to let you know that if changes are committed, then they will not be associated with any named branch.  It is suggested that all modification be placed on a branch. Thus run then command git checkout -b <branch_name> prior to committing any changes.

Pull Command:

git pull <remote> <branch>
Example: git pull origin masterFetch and merge the missing commits from origin‘s master branch into the current working branch.
Description:Pull is similar to fetch, in that it polls the remote repository for any new commits.  However, pull will automatically attempt to merge in the new commits into the current working branch.  Pulling in the new commits is necessary to bring the local branch in sync with the remote branch. FMS Considerations:We suggest using the pull command sparingly.  We find that running a fetch first is more beneficial as it allows the changes to be reviewed prior to blindly applying all new commits.

Branch Command:

git branch [-l] [-f] <branch> [<start-point>]
git branch [-a|-r] [--merged|--no-merged]
Example: git branch user/sdu/my_new_branchCreate a new branch user/sdu/my_new_branch starting from the current working HEAD.
Description:The branch command creates new branches, or lists the local/remote branches.  When creating a branch with the command git branch [-l] [-f] <branch> [<start-point>], the branch is created but the working directory’s current branch does not change.  Use the git checkout <branch> to change to the newly created branch.  Local branches can be listed by simply running git branch without the optional branch name. Remote branch can be listed by adding either the -a (to list all branches, local and remote) or -r (to list only remote branches) options. FMS Considerations:For branches in the FMS repository, the branch name should
follow the pattern user/$user/<branch_name>

Tag Command:

git tag <tag_name> [<commit>]
Example: git tag user/sdu/my_new_tag masterCreate a new tag user/sdu/my_new_branch on the latest commit on the master branch.
Description:Create a new tag from in the repository. FMS Considerations:For tags in the FMS repository, the tag name should follow the pattern user/$user/<tag_name>.Also note, the git tag command is different than the cvs tag command in that you can only create tags with the git version. To create a branch, use the branch or  

Commit Command:

git commit [-a] [-m <message>]
Example: git commit -m 'A commit message'Commit the changes in the index using a commit message of “A commit message”
Description: FMS Considerations:None.

Add Command:

git add [<filepattern>]
Example: git add foo/barAdd file foo/bar as either a file to track, or add the file modifications to the index to be included in the next commit.
Description:Add work in two different ways.  The first is to add files as tracked in git.  This is similar to how add was used in CVS.  The other method is to add file modifications to the index.  The index is a staging area.  File modifications in the index will be included in the next call to git commit. FMS Considerations:None.

Rm Command:

git rm [<filepattern>]
Example: git rm foo/barDelete file foo/bar, and add it’s removal from the index.
Description:git rm deletes the listed file(s) add automatically adds the deletion to the index. FMS Considerations:None.

Mv Command:

git mv <source> <target>
Example: git mv foo/bar bar/fooRenames/Moves the file foo/bar to bar/foo.
Description:Renames/Moved the source file to the target file/destination.  In git, unlike CVS, when a file is renamed, git is still able to keep a complete history of the file modifications.  However, if the file is also modified at the time the rename/move happens, it is possible git will think it is a new file – essentially losing the history.  We suggest doing the file rename/move in one commit and all modifications in a separate commit.  This guarantees the history will be preserved. FMS Considerations:None.

Push Command:

git push <remote_name> <branch_name|tag_name>
Example: git push origin user/foo/barPushed branch/tag named user/foo/bar to the remote “origin”
Description:Pushes the branch/tag to the remote repository to allow others to see/use the modifications.  Since git is a distributed system, all changes made are done to the local repository only. A push is needed to allow the changes to be placed in the remote repository. To allow others to be able to use the modifications, they MUST be pushed. Use the command git remote -v to see the URL and name of the remote repositories. FMS Considerations:User’s will not be able to see any changes until they have been pushed to the gitlab server.