Git installation and configuration#
Installation#
For iX distributions, Git should be in the standard repository.
The git-all package provides a complete Git working environment. Install it with:
$ sudo apt install git-all
To install only Git the `git <https://packages.debian.org/stable/git>`_ package suffices:
$ sudo apt install git
The bash autocompletion makes Git easier to use on the command line. The according package is called bash-completion. Install it with:
$ sudo apt install bash-completion
There are several different ways to install Git on a Mac. Probably the
easiest way to do is to install the Xcode Command Line Tools. For this you
only have to call up git
in the terminal for the first time:
$ git --version
git-completion
you can install with Homebrew:
Then you have to add the following line to the file ~/.bash_profile
:
[[ -r "$(brew --prefix)/etc/profile.d/bash_completion.sh" ]] && . "$(brew --prefix)/etc/profile.d/bash_completion.sh"
Go to https://git-scm.com/download/win and start the download automatically. Further information can be found at https://gitforwindows.org/.
Configuration#
The author of every change needs to be transparent. Specify your name and email address as follows:
$ git config --global user.name "NAME"
defines the name
NAME
associated with your commit transactions.$ git config --global user.email "EMAIL-ADDRESS"
defines the email address
EMAIL-ADDRESS
that will be linked to your commit transactions.
For better readability, activate the coloring of the command line output:
$ git config --global color.ui auto
The ~/.gitconfig
file#
For example, the following file can be created with the commands given above:
[user]
name = veit
email = veit@cusy.io
[color]
ui = auto
However, aliases can also be specified in the ~/.gitconfig
file:
[alias]
st = status
ci = commit
br = branch
co = checkout
df = diff
dfs = diff --staged
See also
Shell-Konfiguration:
The editor can also be specified, for example with:
[core]
editor = vim
or for Visual Studio Code:
[core]
editor = code --wait
Note
On macOS, you must first start Visual Studio Code, then open the command
palette with ⌘+⇧-p and finally execute the Install 'code' command in
PATH
.
The highlighting of space errors in git diff
can also be configured:
[core]
# Highlight whitespace errors in git diff:
whitespace = tabwidth=4,tab-in-indent,cr-at-eol,trailing-space
Note
In addition to ~/.gitconfig
, since version 1.17.12 Git also looks in
~/.config/git/config
for a global configuration file.
Under Linux, ~/.config
can sometimes be a different path set by the
environment variable XDG_CONFIG_HOME
. This behaviour is part of the X
Desktop Group (XDG) specification. You
can get the other path with:
$ echo $XDG_CONFIG_HOME
See also
Since you can set options at multiple levels, you may want to keep track of
where Git reads a particular value from. With git config --list
[1] you can
list all the overridden options and values. You can combine this with
--show-scope
[2] to see where Git is getting the value from:
$ git config --list --show-scope
system credential.helper=osxkeychain
global user.name=veit
global user.email=veit@cusy.io
…
You can also use --show-origin
[3] to list the names of the configuration
files:
$ git config --list --show-origin
file:/opt/homebrew/etc/gitconfig credential.helper=osxkeychain
file:/Users/veit/.config/git/config user.name=veit
file:/Users/veit/.config/git/config user.email=veit@cusy.io
…
Alternative configuration file#
You can use other configuration files for certain working directories, for example to distinguish between private and professional projects. You can use a local configuration in your repository or conditional includes at the end of your global configuration:
…
[includeIf "gitdir:~/private"]
path = ~/.config/git/config-private
This construct ensures that Git includes additional configurations or overwrites
existing ones when you work in ~/private
.
Now create the file ~/.config/git/config-private
and define your
alternative configuration there, for example:
[user]
email = kontakt@veit-schiele.de
[core]
sshCommand = ssh -i ~/.ssh/private_id_rsa
See also
Manage login data#
Since Git version 1.7.9, the access data to git repositories can be managed with gitcredentials. To use this, you can, for example, specify the following:
$ git config --global credential.helper Cache
This will keep your password in the cache for 15 minutes. If necessary, the timeout can be increased, for example with:
$ git config --global credential.helper 'cache --timeout=3600'
With macOS you can use osxkeychain to store the login information. osxkeychain requires Git version 1.7.10 or newer and can be installed in the same directory as Git with:
$ git credential-osxkeychain
git: 'credential-osxkeychain' is not a git command. See 'git --help'.
$ curl -s -O http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain
$ chmod u+x git-credential-osxkeychain
$ sudo mv git-credential-osxkeychain /usr/bin/
Password:
git config --global credential.helper osxkeychain
This enters the following in the ~/.gitconfig
file:
[credential]
helper = osxkeychain
For Windows, Git Credential Manager (GCM) is available. It is integrated in Git for Windows and is installed by default. However, there is also a standalone Installer in Releases.
It is configured with
$ git credential-manager configure
Configuring component 'Git Credential Manager'...
Configuring component 'Azure Repos provider'...
This will add the [credential]
section to your ~.gitconfig
file:
[credential]
helper =
helper = C:/Program\\ Files/Git/mingw64/bin/git-credential-manager.exe
Now, when cloning a repository, a Git Credential Manager window opens and asks you to enter your credentials.
In addition, the ~/.gitconfig
file is supplemented, for example by
the following two lines:
[credential "https://ce.cusy.io"]
provider = generic
Note
You can find a comprehensive example of a ~/.gitconfig
file in my
dotfiles repository: .gitconfig.
The .gitignore
file#
In the .gitignore
file you can exclude files from version management. A
typical .gitignore
file can look like this:
/logs/*
!logs/.gitkeep
/tmp
*.swp
In doing so, Git uses Globbing patterns, among others:
Pattern |
Example |
Description |
---|---|---|
**/logs
|
|
You can put two asterisks to prefix directories anywhere. |
**/logs/instance.log
|
|
You can put two asterisks to prefix files with their name in a parent directory. |
*.log
|
|
An asterisk is a placeholder for null or more characters. |
/logs
!/logs/.gitkeep
|
|
An exclamation mark in front of a pattern ignores it. If a file matches a pattern, but also a negating one that is defined later, it is not ignored. |
/instance.log
|
|
With a preceding slash, the pattern only matches files in the root directory of the repository. |
instance.log
|
|
Usualy the pattern match files in any directory. |
instance?.log
|
|
A question mark fits exactly on a charater. |
instance[0-9].log
|
|
Square brackets can be used to find a single character from a specific range. |
instance[01].log
|
|
Square brackets match a single character from a given set. |
instance[!01].log
|
|
An exclamation mark can be used to find any character from a specified set. |
logs
|
|
If no slash appended, the pattern fix both files and the contents of directories witch this name. |
logs/
|
|
Appending a slash indicates that the pattern is a directory. The entire contents of any directory in the repository that matches the name – including all its files and subdirectories – are ignored. |
var/**/instance.log
|
|
Two Asterisks match null or more directories. |
logs/instance*/error.log
|
|
Wildcards can also be used in directory names. |
logs/instance.log
|
|
Pattern, that specify a particular file in a directory are relative to the root of the repository. |
Git-commit empty folder#
In the example above you can see that with /logs/*
no content of the
logs
directory should be versioned with Git, but an exception is defined
in the following line: !logs/.gitkeep
allows the file .gitkeep
to be
managed with Git. The logs
directory is then also transferred to the Git
repository. This construction is necessary because empty folders cannot be
managed with Git.
Another possibility is to create a .gitignore
file in an empty folder
with the following content:
# ignore everything except .gitignore
*
!.gitignore
excludesfile
#
However, you can also exclude files centrally for all Git repositories. For this
purpose, you can set excludesfile
in the ~/.gitconfig
file:
[core]
# Use custom `.gitignore`
excludesfile = ~/.gitignore
…
Note
You can find helpful templates in my dotfiles repository or on the gitignore.io website.
Ignoring a file from the repository#
If you want to ignore a file that has already been added to the repository in
the past, you need to delete the file from your repository and then add a
.gitignore
rule for it. Using the --cached
option on git rm
means
that the file will be deleted from the repository but will remain in your
working directory as an ignored file.
$ echo *.log >> .gitignore
$ git rm --cached *.log
rm 'instance.log'
$ git commit -m "Remove log files"
Note
You can omit the --cached
option if you want to remove the file from
both the repository and your local file system.
Commit an ignored file#
It is possible to force the commit of an ignored file to the repository with the
-f
(or --force
) option on git add
:
$ cat data/.gitignore
*
$ git add -f data/iris.csv
$ git commit -m "Force add iris.csv"
You might consider this if you have a general pattern (like *
) defined, but
want to commit a specific file. However, a better solution is usually to define
an exception to the general rule:
$ echo '!iris.csv' >> data/.gitignore
$ cat data/.gitignore
*
!iris.csv
$ git add data/iris.csv
$ git commit -m "Add iris.csv"
This approach should be more obvious and less confusing for your team.
Troubleshooting .gitignore
files#
For complicated .gitignore
patterns, or patterns that are spread across
multiple .gitignore
files, it can be difficult to figure out why a
particular file is being ignored.
With git status --ignored=matching
[4], an Ignored Files section is added
to the output, showing all ignored files and directories:
$ git status --ignored=matching
On branch main
Ignored Files:
(use "git add -f <file>...", to pre-mark the changes for committing
.DS_Store
docs/.DS_Store
docs/_build/doctrees/
docs/_build/html/
docs/clean-prep/.ipynb_checkpoints/
…
nothing to commit, working tree clean
You can use the git check-ignore
command with the -v
(or --verbose
)
option to determine which pattern is causing a particular file to be ignored:
$ git check-ignore -v data/iris.csv
data/.gitignore:2:!iris.csv data/iris.csv
The output shows
FILE_CONTAINING_THE_PATTERN:LINE_NUMBER_OF_THE_PATTERN:PATTERN
FILE_NAME
You can pass multiple filenames to git check-ignore
if you like, and the
names themselves don’t even have to match the files that exist in your
repository.
You can get a complete list of all ignored files with git ls-files --ignored
--exclude-standard --others
[5]. With --exclude-standard
the standard
ignored files are read and with --others
the non-versioned files are
displayed instead of the versioned ones:
$ git ls-files --ignored --exclude-standard --others
.DS_Store
_build/doctrees/clean-prep/bulwark.doctree
_build/doctrees/clean-prep/dask-pipeline.doctree
_build/doctrees/clean-prep/deduplicate.doctree
…
Occasionally you may want to bypass the global ~/.gitignore
file to see
which files Git always ignores, regardless of your configuration. You can do
this by switching to another exclude
option, --exclude-per-directory
,
which uses only the repository’s .gitignore
files:
$ git ls-files --ignored --exclude-per-directory=.gitignore --others
docs/_build/doctrees/clean-prep/bulwark.doctree
docs/_build/doctrees/clean-prep/dask-pipeline.doctree
docs/_build/doctrees/clean-prep/deduplicate.doctree
…
Note that the .DS_Store
file is no longer listed as ignored.
If you replace --others
with --cached
, git ls-files
will list files
that would be ignored unless they have already been committed:
$ git ls-files --ignored --exclude-per-directory=.gitignore --cached
data/iris.csv
You may have such files because someone added them to a .gitignore
file
before the relevant patterns, or because someone added them with git add
--force
. Either way, if you no longer want to manage the file with Git, you
can remove it from Git management with the following one-liner, but don’t
delete it:
$ git ls-files --ignored --exclude-per-directory=.gitignore --cached | xargs -r git rm --cached
rm 'data/iris.csv'