Git Configuration Standards & Recommendations¶
This page collects advice for configuring Git for DM development.
Some of these configurations are mentioned in the DM Development Workflow with Git, GitHub, JIRA and Jenkins. Such configurations are labeled on as page as required (as opposed to recommended practices).
See also:
DM Development Workflow with Git, GitHub, JIRA and Jenkins for guidance on how we use Git, including:
Learning Git¶
If you’re new to Git, there are many great learning resources, such as
Git’s online docs, and the associated online Pro Git book by Scott Chacon and Ben Staubb.
GitHub Help, which covers fundamental git usage too.
Use your institution’s email with Git & GitHub¶
We use Git commit authorship metadata to audit copyrights in DM code (RFC-45, for background).
In Git (required configuration)¶
Ensure that Git is set up to use your institution-hosted email address (only AURA employees should use their lsst.org
email addresses) in the ~/.gitconfig
file.
You can do this from the command line:
git config --global user.name "Your Name"
git config --global user.email "your_email@institution.edu"
You might not want to use your institution’s email when you contribute to non-LSST projects.
Since Git 2.13, you can set directory-based conditional configurations.
For example, if you always work on LSST projects from your ~/lsst/
directory, you can add this to the bottom of your ~/.gitconfig
file:
[includeIf "gitdir:~/lsst/"]
path = .gitconfig-lsst
Then in a ~/.gitconfig-lsst
file, set your LSST-specific configurations:
[user]
name = Your Name
email = your_email@institution.edu
Whenever you work on a repository inside ~/lsst/
, the configurations in ~/.gitconfig-lsst
are applied, and possibly override previous configurations from the ~/.gitconfig
file.
On GitHub¶
Likewise, in your GitHub account email settings, add your institution-hosted email.
We recommend that you set this institutional email as your Primary GitHub email address. This step ensures that Git commits you make directly on GitHub.com (such as quick documentation fixes) and merges made via the ‘big green button’ have proper authorship metadata. Alternatively, remember to choose your institution email from the email address drop-down menu before committing. See the GitHub help page Editing files in your repository for details.
Set up Two-Factor Authentication (2FA) for GitHub¶
GitHub now requires Two-Factor Authentication (2FA) to work with repos via HTTPS. Configure it through your GitHub account security settings. 2FA means that you’ll have to enter an authentication code when logging into GitHub.com from a new computer. Apps like 1Password (see their guide), Authy, and the Google Authenticator App can help you generate these authentication codes. When pushing commits with a 2FA-enabled account, you’ll use a personal access token instead of your password. Follow the instructions below to set up a credential helper and create authentication tokens.
Set up a Git credential helper¶
Rather than entering your GitHub username and 2FA authentication token or ssh key every time you push, you should set up a Git credential helper to manage this for you. A credential helper is especially important for working with our Git LFS-backed repositories.
Mac users can use the secure macOS keychain:
git config --global credential.helper osxkeychain
Linux users can use a credential cache to temporarily keep credentials in memory. To have your credentials cached for 1 hour (3600 seconds):
git config --global credential.helper 'cache --timeout=3600'
Linux users can alternatively have their credentials stored on disk in a ~/.git-credentials
file.
Only do this for machines where you can ensure some level of security.
To do this securely on USDF, set the credential file to be only read/write by your user: chmod 0600 ~/.git-credentials
.
git config --global credential.helper store
Once a credential helper is enabled, the next time you git push
, you will add your credentials to the helper.
If you are using HTTPS access, you will need to create and use a personal access token instead of your GitHub password, as described below.
Git authentication tokens¶
Due to GitHub’s authentication interface, you must use a personal access token instead of a password when pushing to GitHub via HTTPS. GitHub access via ssh does not require a token, but we have more experience working with Git LFS repos via HTTPS. A credential helper, as described above, will let you cache this token, so you do not have to save it (you can only view it on GitHub when you generate it). Create a personal token at GitHub Personal Access Tokens, using the “generate new token” button in the upper right, with the “classic” interface. Give it a name (e.g. “LSST USDF”), choose an expiration date (when the token expires you will have to generate a new one and re-enter it into your credential cache), and set the following permissions:
repo->public_repo
workflow
The next time you run a Git command that requires authentication, Git will ask you to authenticate with both GitHub (for the push via HTTPS) and, if you are pushing to a Git LFS repo, with LSST’s Git LFS server (for authentication of the LFS upload):
Username for 'https://github.com': <GitHub username>
Password for 'https://<user>@github.com': <GitHub token>
Username for 'https://git-lfs.lsst.codes': <GitHub username>
Password for 'https://<user>@git-lfs.lsst.codes': <GitHub token>
At the prompts, enter your GitHub username and token.
Once your credentials are cached, you won’t need to repeat this process on your system (unless you opted for the cache-based credential helper) until the token expires.
If you find that git push
is not working but also not asking you for credentials, you may need to manually insert the username and token into the credential store or macOS keychain, or manually delete the token and let it re-authenticate; ask for help on Slack if you are having trouble.
Tune your shell for Git¶
You can build an effective development environment and workflow by tuning your Git setup. Here are some ideas:
Add git status to your prompt (see the instructions under “To enable:” at the top of the file). Some more complicated suggestions are discussed on this Community thread, including this git bash prompt project. Colorized git information in your prompt can help you easily know what branch you are on, or if you forgot to finish a rebase.
Enable shell autocompletion, to allow things like tab-completing git branch names and files to commit. Linux users can install the “bash-completion” package to automatically gain this, and other, autocomplete functionality. MacOS users can add
autoload -Uz compinit && compinit
to their.zshrc
file.Use hub to interact with GitHub features from the command line.
Set up your editor¶
You’ll want to configure your preferred editor (or its command line hook) as your Git editor. For example:
git config --global core.editor "vim"
git config --global core.editor "emacs"
git config --global core.editor "atom --wait"
git config --global core.editor "subl -n -w"
See GitHub’s help for setting up Atom and Sublime Text as Git editors.
Useful Git aliases and configurations¶
You can craft custom Git commands (aliases) in your ~/.gitconfig
to refine your workflow.
When you run an alias (git <alias> [arguments]
) the alias’s name is effectively replaced with the alias’s content in the command line statement.
Here are some aliases try in ~/.gitconfig
:
[alias]
# List things
tags = "tag -l"
branches = "branch -a"
remotes = "remote -v"
# Shorten common commands
co = "checkout"
st = "status"
br = "branch"
ci = "commit"
d = "diff"
# Log that shows titles of last 16 commits
l = "log -16 --color=always --all --topo-order --pretty='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
# Log that starts a pager with titles of all the commits in your tree
ll = log --color=always --all --topo-order --pretty='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
# Log that shows the last 10 commits as a graph
lg = "log -10 --color=always --all --graph --topo-order --pretty='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
# Log that shows all commits as a graph (using a pager)
lgl = "log --color=always --all --graph --topo-order --pretty='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
# Show outgoing commits
out = "log @{u}.."
# Print the title of the current branch; sometimes useful for scripting
currentbranch = "!git branch --contains HEAD | grep '*' | tr -s ' ' | cut -d ' ' -f2"
# Better diffs for prose
wdiff = "diff --color-words"
# Safer pulls; don't do anything other than a fast forward on merge
pull = "pull --ff-only"
# Amend last commit without modifying commit message
amend = "!git log -n 1 --pretty=tformat:%s%n%n%b | git commit -F - --amend"
# Create a commit that will be automatically squashed as a fixup when you
# run `git rebase --autosquash`
fixup = "commit --fixup=HEAD"
Configure ‘plain’ pushes in Git (required for Git prior to v2.0)¶
Note
This behavior is the default for Git v2.0 and later; this section is only here for reference for those coming from an earlier version of git who may have set a different config option for this.
In earlier versions of Git, push.default=matching
was the default.
See the git-config documentation for details.
Ensure that git push
only pushes your currently checked-out branch by running this command:
git config --global push.default simple
This command modifies ~/.gitconfig
.