Git
Chapters ▾ 2nd Edition

10.8 Funcionamento Interno do Git - Variáveis de ambiente

Variáveis de ambiente

O Git sempre é executado no terminal bash, e usa um certo conjunto de variáveis de ambiente para determinar como ele se comporta. Ocasionalmente, é útil saber o que são e como podem ser usadas para fazer o Git se comportar da maneira que você deseja. Esta não é uma lista completa de todas as variáveis de ambiente às quais o Git presta atenção, mas cobriremos as mais úteis.

Comportamentos globais

Parte do comportamento geral do Git como um programa de computador depende de variáveis de ambiente.

GIT_EXEC_PATH determina onde o Git procura seus subprogramas (como git-commit, git-diff, e outros). Você pode verificar a configuração atual executando git --exec-path.

HOME geralmente não é considerado customizável (muitas outras coisas dependem disso), mas é onde o Git procura o arquivo de configuração global. Se você quer uma instalação do Git realmente portátil, que seja completa com configuração global, você pode sobrescrever HOME no ambiente do terminal onde o Git portátil será executado.

PREFIX é semelhante, mas é voltado para a configuração de sistema. O Git procura por este arquivo em $PREFIX/etc/gitconfig.

GIT_CONFIG_NOSYSTEM, quando definido, desativa o uso do arquivo de configuração de sistema. Isso é útil se a configuração do sistema está interferindo nos comandos, mas você não tem acesso para alterá-la ou removê-la.

GIT_PAGER controla o programa usado para exibir a saída de múltiplas páginas na linha de comando. Se não for definido, PAGER será usado como um substituto.

GIT_EDITOR é o editor que o Git iniciará quando o usuário precisar editar algum texto (uma mensagem de commit, por exemplo). Se não for definido, EDITOR será usado.

Repository Locations

Git uses several environment variables to determine how it interfaces with the current repository.

GIT_DIR is the location of the .git folder. If this isn’t specified, Git walks up the directory tree until it gets to ~ or /, looking for a .git directory at every step.

GIT_CEILING_DIRECTORIES controls the behavior of searching for a .git directory. If you access directories that are slow to load (such as those on a tape drive, or across a slow network connection), you may want to have Git stop trying earlier than it might otherwise, especially if Git is invoked when building your shell prompt.

GIT_WORK_TREE is the location of the root of the working directory for a non-bare repository. If not specified, the parent directory of $GIT_DIR is used.

GIT_INDEX_FILE is the path to the index file (non-bare repositories only).

GIT_OBJECT_DIRECTORY can be used to specify the location of the directory that usually resides at .git/objects.

GIT_ALTERNATE_OBJECT_DIRECTORIES is a colon-separated list (formatted like /dir/one:/dir/two:…) which tells Git where to check for objects if they aren’t in GIT_OBJECT_DIRECTORY. If you happen to have a lot of projects with large files that have the exact same contents, this can be used to avoid storing too many copies of them.

Pathspecss

Um “pathspec” refere-se a como você especifica caminhos para coisas no Git, incluindo o uso de curingas (wildcards). Eles são usados no arquivo .gitignore, mas também na linha de comando (git add *.c).

GIT_GLOB_PATHSPECS e GIT_NOGLOB_PATHSPECS controlam o comportamento padrão dos curingas em pathspecs. Se GIT_GLOB_PATHSPECS for definido como 1, os caracteres curinga agem como curingas (que é o padrão); se GIT_NOGLOB_PATHSPECS for definido como 1, os caracteres curinga apenas combinam com eles mesmos, o que significa que algo como`.c` iria apenas corresponder a um arquivo com o nome.c”, ao invés de qualquer arquivo cujo nome termine com .c. Você pode sobrescrever isso em casos individuais iniciando o pathspec com :(glob) ou :(literal), assim como em :(glob)*.c.

GIT_LITERAL_PATHSPECS desativa ambos os comportamentos acima; nenhum caractere curinga funcionará e os prefixos de substituição também ficarão desabilitados.

GIT_ICASE_PATHSPECS define todos os pathspecs para funcionarem sem distinção entre maiúsculas e minúsculas.

Fazendo commits

A criação final de um commit, que é um objeto Git, geralmente é feita por git-commit-tree, que usa essas variáveis de ambiente como sua fonte primária de informação, usando os valores de configuração apenas se essas não estiverem presentes.

GIT_AUTHOR_NAME é um nome legível para o campo “author”.

GIT_AUTHOR_EMAIL é o email para o campo “author”.

GIT_AUTHOR_DATE é a data e hora (timestamp) para o campo “author”.

GIT_COMMITTER_NAME define um nome legível para o campo “committer”.

GIT_COMMITTER_EMAIL é o email para o campo “committer”.

GIT_COMMITTER_DATE é a data e hora (timestamp) para o campo “committer”.

EMAIL é o endereço de e-mail substituto caso o valor de configuração user.email não esteja definido. Se esse não estiver definido, o Git substitui pelo usuário do sistema e nome do computador (hostname).

Rede e Internet

Git usa a biblioteca curl para fazer operações de rede sobre HTTP, então ` GIT_CURL_VERBOSE` diz ao Git para emitir todas as mensagens geradas por aquela biblioteca. Isso é semelhante a fazer curl -v na linha de comando.

GIT_SSL_NO_VERIFY diz ao Git para não verificar os certificados SSL. Às vezes, isso pode ser necessário se você estiver usando um certificado autoassinado para servir repositórios Git sobre HTTPS ou se estiver no meio da configuração de um servidor Git, mas ainda não instalou um certificado completo.

Se a taxa de dados de uma operação HTTP for inferior a GIT_HTTP_LOW_SPEED_LIMIT bytes por segundo por mais de GIT_HTTP_LOW_SPEED_TIME segundos, o Git irá abortar a operação. Esses valores substituem os valores de configuração http.lowSpeedLimit e http.lowSpeedTime.

  • GIT_HTTP_USER_AGENT* define a string do agente do usuário usada pelo Git ao se comunicar por HTTP. O padrão é um valor como git/2.0.0.

Diffing and Merging

GIT_DIFF_OPTS is a bit of a misnomer. The only valid values are -u<n> or --unified=<n>, which controls the number of context lines shown in a git diff command.

GIT_EXTERNAL_DIFF is used as an override for the diff.external configuration value. If it’s set, Git will invoke this program when git diff is invoked.

GIT_DIFF_PATH_COUNTER and GIT_DIFF_PATH_TOTAL are useful from inside the program specified by GIT_EXTERNAL_DIFF or diff.external. The former represents which file in a series is being diffed (starting with 1), and the latter is the total number of files in the batch.

GIT_MERGE_VERBOSITY controls the output for the recursive merge strategy. The allowed values are as follows:

  • 0 outputs nothing, except possibly a single error message.

  • 1 shows only conflicts.

  • 2 also shows file changes.

  • 3 shows when files are skipped because they haven’t changed.

  • 4 shows all paths as they are processed.

  • 5 and above show detailed debugging information.

The default value is 2.

Debugging

Want to really know what Git is up to? Git has a fairly complete set of traces embedded, and all you need to do is turn them on. The possible values of these variables are as follows:

  • “true”, “1”, or “2” – the trace category is written to stderr.

  • An absolute path starting with / – the trace output will be written to that file.

GIT_TRACE controls general traces, which don’t fit into any specific category. This includes the expansion of aliases, and delegation to other sub-programs.

$ GIT_TRACE=true git lga
20:12:49.877982 git.c:554               trace: exec: 'git-lga'
20:12:49.878369 run-command.c:341       trace: run_command: 'git-lga'
20:12:49.879529 git.c:282               trace: alias expansion: lga => 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.879885 git.c:349               trace: built-in: git 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.899217 run-command.c:341       trace: run_command: 'less'
20:12:49.899675 run-command.c:192       trace: exec: 'less'

GIT_TRACE_PACK_ACCESS controls tracing of packfile access. The first field is the packfile being accessed, the second is the offset within that file:

$ GIT_TRACE_PACK_ACCESS=true git status
20:10:12.081397 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 12
20:10:12.081886 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 34662
20:10:12.082115 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 35175
# […]
20:10:12.087398 sha1_file.c:2088        .git/objects/pack/pack-e80e...e3d2.pack 56914983
20:10:12.087419 sha1_file.c:2088        .git/objects/pack/pack-e80e...e3d2.pack 14303666
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

GIT_TRACE_PACKET enables packet-level tracing for network operations.

$ GIT_TRACE_PACKET=true git ls-remote origin
20:15:14.867043 pkt-line.c:46           packet:          git< # service=git-upload-pack
20:15:14.867071 pkt-line.c:46           packet:          git< 0000
20:15:14.867079 pkt-line.c:46           packet:          git< 97b8860c071898d9e162678ea1035a8ced2f8b1f HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2.0.4
20:15:14.867088 pkt-line.c:46           packet:          git< 0f20ae29889d61f2e93ae00fd34f1cdb53285702 refs/heads/ab/add-interactive-show-diff-func-name
20:15:14.867094 pkt-line.c:46           packet:          git< 36dc827bc9d17f80ed4f326de21247a5d1341fbc refs/heads/ah/doc-gitk-config
# […]

GIT_TRACE_PERFORMANCE controls logging of performance data. The output shows how long each particular git invocation takes.

$ GIT_TRACE_PERFORMANCE=true git gc
20:18:19.499676 trace.c:414             performance: 0.374835000 s: git command: 'git' 'pack-refs' '--all' '--prune'
20:18:19.845585 trace.c:414             performance: 0.343020000 s: git command: 'git' 'reflog' 'expire' '--all'
Counting objects: 170994, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (43413/43413), done.
Writing objects: 100% (170994/170994), done.
Total 170994 (delta 126176), reused 170524 (delta 125706)
20:18:23.567927 trace.c:414             performance: 3.715349000 s: git command: 'git' 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-49190-pack'
20:18:23.584728 trace.c:414             performance: 0.000910000 s: git command: 'git' 'prune-packed'
20:18:23.605218 trace.c:414             performance: 0.017972000 s: git command: 'git' 'update-server-info'
20:18:23.606342 trace.c:414             performance: 3.756312000 s: git command: 'git' 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago'
Checking connectivity: 170994, done.
20:18:25.225424 trace.c:414             performance: 1.616423000 s: git command: 'git' 'prune' '--expire' '2.weeks.ago'
20:18:25.232403 trace.c:414             performance: 0.001051000 s: git command: 'git' 'rerere' 'gc'
20:18:25.233159 trace.c:414             performance: 6.112217000 s: git command: 'git' 'gc'

GIT_TRACE_SETUP shows information about what Git is discovering about the repository and environment it’s interacting with.

$ GIT_TRACE_SETUP=true git status
20:19:47.086765 trace.c:315             setup: git_dir: .git
20:19:47.087184 trace.c:316             setup: worktree: /Users/ben/src/git
20:19:47.087191 trace.c:317             setup: cwd: /Users/ben/src/git
20:19:47.087194 trace.c:318             setup: prefix: (null)
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Miscellaneous

GIT_SSH, if specified, is a program that is invoked instead of ssh when Git tries to connect to an SSH host. It is invoked like $GIT_SSH [username@]host [-p <port>] <command>. Note that this isn’t the easiest way to customize how ssh is invoked; it won’t support extra command-line parameters, so you’d have to write a wrapper script and set GIT_SSH to point to it. It’s probably easier just to use the ~/.ssh/config file for that.

GIT_ASKPASS is an override for the core.askpass configuration value. This is the program invoked whenever Git needs to ask the user for credentials, which can expect a text prompt as a command-line argument, and should return the answer on stdout. (See Credential Storage for more on this subsystem.)

GIT_NAMESPACE controls access to namespaced refs, and is equivalent to the --namespace flag. This is mostly useful on the server side, where you may want to store multiple forks of a single repository in one repository, only keeping the refs separate.

GIT_FLUSH can be used to force Git to use non-buffered I/O when writing incrementally to stdout. A value of 1 causes Git to flush more often, a value of 0 causes all output to be buffered. The default value (if this variable is not set) is to choose an appropriate buffering scheme depending on the activity and the output mode.

GIT_REFLOG_ACTION lets you specify the descriptive text written to the reflog. Here’s an example:

$ GIT_REFLOG_ACTION="my action" git commit --allow-empty -m 'my message'
[master 9e3d55a] my message
$ git reflog -1
9e3d55a HEAD@{0}: my action: my message