Configuring Git for Drupal

Last updated on
21 January 2025

The following steps will need to be done on each installation of Git you use to contribute to Drupal (home, office, laptop, etc.).

Git configuration files

Git configuration is stored in a plain-text configuration file called .gitconfig. You have the choice of configuring Git globally or on a per-repository basis.

Global

The global Git configuration file is in your home directory:

  • On Unix-like systems (OS X, Linux, BSD, WSL2): ~/.gitconfig
  • On Windows: C:\Users\[username]\.gitconfig

You can open or create the configuration in your terminal using the command:
git config -e --global

Alternatively, you can create or edit the .gitconfig file as you would any text file.

Per-repository

If you want to change the configuration for a particular Git repository, run this command in your terminal, from the top level of the repository:

git config -e

Alternatively, you can edit the .gitconfig file at the top level of the repository, as you would any text file.

Show configuration

To see the current configuration, run this command either at the global or repository level:

git config --list

Add the --show-origin option to show where the configuration is defined:

git config --list --show-origin

Git GUI tools

The configuration commands and files mentioned here are designed for use with Git on the command line. If you are using a Git GUI client or an IDE with integrated Git features, you will need to configure it separately. Look for a "Preferences" or "Settings" menu, usually under "Tools" or "Edit", to adjust Git settings in your tool. Refer to the tool's documentation for specific instructions.

Identifying yourself to Git

To be properly credited for your contributions on Drupal.org, you must identify yourself to Git.

To identify yourself, you will need to run two commands either in your home directory or in specific repositories (see section above). Personalized versions of these commands with your details filled in can be found from your Drupal.org user profile page by clicking on DrupalCode access, and then locating the Git configuration section of the page.

Here are the commands:

git config --global user.name "User name"
git config --global user.email user@example.com
  • It is customary to use your full name for User Name.
  • The email address you use when you identify yourself is added to Git’s commit data and creates the link between your commit and your Drupal.org account. So the value of user.email in your configuration must correspond to an email address linked to your account. To keep your email address private, you can use your anonymized address by using the command shown at the bottom of your DrupalCode access page.

Configuring Git behavior

To configure Git for use on the command line, add the following configuration directives to the appropriate .gitconfig file.

Always use Unix line-endings in checked out files

[core]
  autocrlf = false
  safecrlf = false

All code and patches will use Unix line-endings (LF) instead of Windows line-endings (CRLF). Unix line-endings are the common standard in open-source projects.

Do not ignore letter casing in filenames on case-insensitive filesystems (like FAT on Windows)

[core]
  ignorecase = false

Note: Even with this setting, Git might not catch some file/directory renames. In those cases, the only workaround is:

git mv original original.tmp
git mv original.tmp Original

Automatically rebase when pulling

[branch]
  autosetuprebase = always

This setting prevents accidental "merge bubbles" (detailed explanation) and is recommended for working on Drupal.org projects. (You still can, and should, merge explicitly when adding large change sets; the purpose is just to prevent unintentional merges when pushing.)

Use color highlighting for diffs and the git log

[color]
  ui = true

Optimize diffs for renamed and copied files

[diff]
  renames = copies

When renaming or copying files, git diff will not show the entire file content for the rename/copy, but merely a single line denoting the rename/copy instead. Subsequent diff hunks in a patch may perform additional changes to the renamed/copied file. This keeps patches small.

Note: git diff/format-patch sometimes may not adhere to renames = copies. The actual limit is not documented, but git only checks for renames/copies up to a similarity of 50-70%. In order to enforce the renames/copies diff behavior, pass an explicit smaller limit:

git diff -M25%

Do not use values lower than 25%, since that will cause git to find false-positive matches on source files (i.e. "copying" a completely different file that just happens to be somewhere in the code-base).

Note: Patches involving renamed and/or copied files will be incompatible with patch file parsers that do not support this diff extension from git.

Define alias properly for applying patches

[alias]
  a = apply --index

git a some.patch will apply the patch and also add any new/renamed/copied/deleted files accordingly to Git's index, so you do not forget to add them manually before committing the patch.

Check out new branches from origin by default

[checkout]
  defaultRemote = origin

With Drupal.org's GitLab integration, many developers will have multiple remotes for issue forks. This configuration will allow Git to check out branches from origin (the main core repository) by default. There are copy-and-paste commands available on issues for checking out branches within the issue repository remote.

Global .gitignore file

You will also need to configure a .gitignore file, which tells Git to ignore certain files and not add them to the Git repository.

Start by adding this configuration to the appropriate .gitconfig file (changing the path to the file if necessary):

[core]
  excludesfile = ~/.gitignore

Then put the following code into the .gitignore file:

# Patch/diff artifacts.
*.patch
*.diff
*.orig
*.rej
interdiff*.txt

# emacs artifacts.
*~
\#*\#

# VI swap file.
*.swp

# Hidden files.
.DS*
.project

# Windows links.
*.lnk

# Temporary files.
tmp*

# Exclude IDE's project directory.
nbproject
.idea

# For Drupal 7, comment the following lines.
vendor
core/node_modules

Thus, Git will ignore all .patch, .orig, .rej, .lnk and other files and directories, everywhere. You can still force-add an ignored file by doing git add -f my.patch, but that is not usually necessary.

Complete ~/.gitconfig

After adding the recommended configuration described above, your .gitconfig file would contain this code:

[core]
  autocrlf = false
  safecrlf = false
  ignorecase = false
  excludesfile = ~/.gitignore
[branch]
  autosetuprebase = always
[diff]
  renames = copies
[color]
  ui = true
[alias]
  a = apply --index
[checkout]
  defaultRemote = origin

Advanced Git configuration

Git aliases

Git aliases are a powerful way to streamline your most frequent Git operations. Read a basic tutorial here. Git Immersion also has a section for aliases. Here are some useful Git aliases:

  • git diffup - Create full patch, interdiff.txt, and commit log in one shot for sandbox patches.

    Applies to:

    • Larger or more complex core patches, which are developed and improved in a sandbox branch.

    Assumptions:

    • You won't push commits upstream before you create a patch for a d.o issue.
    • You want to combine and enforce best practices:
      1. Obviously, providing interdiffs for others.
      2. Doing atomic and clean commits.
      3. Writing proper commit messages.
        (The shortlog can be copied 1:1 into an issue comment.)
    • Your local branch foo tracks the upstream mysandbox/foo branch.

      To configure/enforce this for existing branches:

      git branch --set-upstream foo mysandbox/foo
      

    Alias:

    git config --global alias.diffup '!git log --oneline --first-parent --reverse @{u}... && git diff 8.x... > $1 && git diff @{u} > interdiff.txt && echo'
    

    Explanation:

    1. Outputs the commit messages of all new commits that haven't pushed to upstream yet to the console/stdout. (ready to be copied 1:1 into an issue comment)
    2. Creates a patch file containing all changes from the current branch since it diverged from 8.x.
    3. Creates an interdiff between (old) upstream and the current local branch.

    Usage:

    1. $ git diffup effort.topic.patch
      

      creates:

      • ./effort.topic.patch
      • ./interdiff.txt

      and shows the log; e.g.:

      e20b52b Copied ConfigTest into Drupal\Core\...
      7f20970 Added generic ConfigThingie with ab...
      6b92dac Renamed ConfigThingie::load() into ...
      
    2. After updating the d.o issue, push your local changes into the upstream sandbox branch.
  • git rmbranch - Delete and prune a branch locally + remotely.

    Applies to:

    • Heavy branch users.

    Assumptions:

    • You (and no one else) needs the specified branch anymore.

    Alias:

    git config --global alias.rmbranch '!git branch -d $1 && git push origin --delete'
    

    Explanation:

    1. Deletes the local branch of the given name.
    2. If successful, deletes the remote branch of the given name.

    Usage:

    1. $ git rmbranch myfeature-sun
      

    Benefits:

    • Due to the appearance of "branch" in the alias, your shell might autocomplete branch names.
  • git ac patch-url - Download and apply a patch in one command.

    Alias:

    In ~/.gitconfig:

    [alias]
    # Download and apply a patch.
            a = apply --index
            ac = "!f() { curl $@ | git a; }; f"
    

    Usage:

    git ac http://drupal.org/patch-url.patch
    

Configuring attributes for improved diffs

Git can detect the correct function context for diffs based on the language. By default, Git doesn't know which language is used in specific file types. To improve diff output for Drupal-related files, you can configure Git attributes to treat these files as PHP files for diff purposes.

Create a Git attributes file at $HOME/.config/git/attributes. If you use the XDG_CONFIG_HOME environment variable, the file should be placed at $XDG_CONFIG_HOME/git/attributes. Add the following lines to the file:

*.engine   diff=php
*.inc      diff=php
*.install  diff=php
*.module   diff=php
*.php      diff=php
*.profile  diff=php
*.test     diff=php
*.theme    diff=php

This configuration tells Git to apply PHP-specific diff settings to common Drupal file extensions, enhancing the readability and context of code changes.

For more details, see the Git attributes documentation.

Tags

Help improve this page

Page status: No known problems

You can: