config

installation

[!NOTE|label:references:]

  • ubuntu

    $ sudo add-apt-repository ppa:git-core/ppa
    $ sudo apt update
    $ sudo apt install git

from source

[!NOTE|label:references:]

  • dependencies

    [!NOTE|label:references:]

    • git-core

      # debian
      $ sudo apt install -y dh-autoreconf libexpat1-dev gettext libz-dev libssl-dev
      $ sudo apt install -y libcurl4-openssl-dev
      $ sudo apt install -y libcurl4-gnutls-dev
      
      # centos/rhel
      $ sudo dnf config-manager --set-enabled powertools
      $ sudo dnf install epel-release epel-next-release
      $ sudo dnf install -y dh-autoreconf libcurl-devel curl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel
      
      # osx
      $ brew install gcc autoconf automake openssl@3 expat gettext zlib libtool libiconv ncurses
      $ brew install perl
      $ sudo PERL_MM_OPT="INSTALL_BASE=$HOME/perl5" cpan local::lib
      $ eval "$(sudo perl -I$HOME/perl5/lib/perl5 -Mlocal::lib=$HOME/perl5)"
    • git-doc

      # debian
      $ sudo apt install -y asciidoc xmlto docbook2x hunspell libhunspell-dev
      
      # centos/rhel
      $ sudo dnf install -y asciidoc xmlto docbook2X docbook-style-xsl
      # or
      $ sudo dnf install -y --enablerepo=*epel* docbook2X
      $ sudo ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi
      
      # osx
      $ brew install asciidoc xmlto docbook2x docbook-xsl hunspell
      $ ln -sf /usr/local/bin/docbook2texi /usr/local/bin/docbook2x-texi
    • git-info

      # debian
      $ sudo apt install -y install-info
      
      # centos/rhel
      $ sudo dnf install -y util-linux
      # deprecated
      $ sudo dnf install -y getopt
      
      # osx
      $ brew install gnu-getopt
    • others

      # audio output
      $ apt install libao-dev
      
      # centos
      $ sudo dnf install -y libao libao-devel
      
      # osx
      $ brew install libao
  • install

    [!NOTE|label:release package:]

    $ curl -fsSL https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.42.0.tar.gz |
           tar -zxf -C ${iRCHOME}/utils/git &&
      cd ${iRCHOME}/utils/git
    
    $ make configure
    $ ./configure --prefix=/usr/local --with-shell=/usr/local/bin/bash
    $ make -j all doc info
    $ sudo make install install-doc install-html install-info
    
    # additional
    $ chmod +x ${iRCHOME}/utils/git/contrib/completion/*
    $ sudo ln -sf ${iRCHOME}/utils/git/contrib/completion/git-prompt.sh       /usr/local/libexec/git-core/git-prompt.sh
    $ sudo ln -sf ${iRCHOME}/utils/git/contrib/completion/git-completion.bash /usr/share/bash-completion/completions/git
    # or
    $ sudo ln -sf ${iRCHOME}/utils/git/contrib/completion/*                   /usr/share/doc/git/contrib/completion/
    $ sudo ln -sf ${iRCHOME}/utils/git/contrib/completion/git-completion.bash /usr/share/bash-completion/completions/git
    • result

      # git-for-windows
      $ git --version
      git version 2.42.0.windows.2.5.g49aad3ca52
      
      # git
      $ git --version
      git version 2.42.0.325.g3a06386e31
    • pacakges:

      [!TIP|label:check apt package bin path without install:]

      $ sudo apt-file list git
      • bins : /usr/local/bin

      • git-core : /usr/local/libexec/git-core or $ git --exec-path

      • diff-highlight : /usr/share/doc/git/contrib/diff-highlight/diff-highlight

      • git-prompt.sh : /usr/local/libexec/git-core/git-prompt.sh

      • git-completion : /usr/share/bash-completion/completions/git

      • git-info : /usr/local/share/info

    bindir=$(cd '/usr/local/bin' && pwd) && \
    execdir=$(cd '/usr/local/libexec/git-core' && pwd) && \
    destdir_from_execdir_SQ=$(echo 'libexec/git-core' | sed -e 's|[^/][^/]*|..|g') && \
    { test "$bindir/" = "$execdir/" || \
      for p in git scalar git-shell git-cvsserver; do \
            rm -f "$execdir/$p" && \
            test -n "" && \
            ln -s "$destdir_from_execdir_SQ/bin/$p" "$execdir/$p" || \
            { test -z "" && \
              ln "$bindir/$p" "$execdir/$p" 2>/dev/null || \
              cp "$bindir/$p" "$execdir/$p" || exit; } \
      done; \
    } && \
    for p in git-receive-pack git-upload-archive git-upload-pack; do \
            rm -f "$bindir/$p" && \
            test -n "" && \
            ln -s "git" "$bindir/$p" || \
            { test -z "" && \
              ln "$bindir/git" "$bindir/$p" 2>/dev/null || \
              ln -s "git" "$bindir/$p" 2>/dev/null || \
              cp "$bindir/git" "$bindir/$p" || exit; }; \
    done && \
    for p in git-add git-am git-annotate git-apply git-archive git-bisect git-blame git-branch git-bugreport git-bundle git-cat-file git-check-attr git-check-ignore git-check-mailmap git-check-ref-format git-checkout--worker git-checkout-index git-checkout git-clean git-clone git-column git-commit-graph git-commit-tree git-commit git-config git-count-objects git-credential-cache--daemon git-credential-cache git-credential-store git-credential git-describe git-diagnose git-diff-files git-diff-index git-diff-tree git-diff git-difftool git-fast-export git-fast-import git-fetch-pack git-fetch git-fmt-merge-msg git-for-each-ref git-for-each-repo git-fsck git-fsmonitor--daemon git-gc git-get-tar-commit-id git-grep git-hash-object git-help git-hook git-index-pack git-init-db git-interpret-trailers git-log git-ls-files git-ls-remote git-ls-tree git-mailinfo git-mailsplit git-merge-base git-merge-file git-merge-index git-merge-ours git-merge-recursive git-merge-tree git-merge git-mktag git-mktree git-multi-pack-index git-mv git-name-rev git-notes git-pack-objects git-pack-redundant git-pack-refs git-patch-id git-prune-packed git-prune git-pull git-push git-range-diff git-read-tree git-rebase git-receive-pack git-reflog git-remote-ext git-remote-fd git-remote git-repack git-replace git-rerere git-reset git-rev-list git-rev-parse git-revert git-rm git-send-pack git-shortlog git-show-branch git-show-index git-show-ref git-sparse-checkout git-stash git-stripspace git-submodule--helper git-symbolic-ref git-tag git-unpack-file git-unpack-objects git-update-index git-update-ref git-update-server-info git-upload-archive git-upload-pack git-var git-verify-commit git-verify-pack git-verify-tag git-worktree git-write-tree git-cherry git-cherry-pick git-format-patch git-fsck-objects git-init git-maintenance git-merge-subtree git-restore git-show git-stage git-status git-switch git-version git-whatchanged; do \
            rm -f "$execdir/$p" && \
            if test -z ""; \
            then \
                    test -n "" && \
                    ln -s "$destdir_from_execdir_SQ/bin/git" "$execdir/$p" || \
                    { test -z "" && \
                      ln "$execdir/git" "$execdir/$p" 2>/dev/null || \
                      ln -s "git" "$execdir/$p" 2>/dev/null || \
                      cp "$execdir/git" "$execdir/$p" || exit; }; \
            fi \
    done && \
    remote_curl_aliases="git-remote-https git-remote-ftp git-remote-ftps" && \
    for p in $remote_curl_aliases; do \
            rm -f "$execdir/$p" && \
            test -n "" && \
            ln -s "git-remote-http" "$execdir/$p" || \
            { test -z "" && \
              ln "$execdir/git-remote-http" "$execdir/$p" 2>/dev/null || \
              ln -s "git-remote-http" "$execdir/$p" 2>/dev/null || \
              cp "$execdir/git-remote-http" "$execdir/$p" || exit; } \
    done
    install -d -m 755 '/usr/local/share/man/man3'
    (cd perl/build/man/man3 && tar cf - .) | \
    (cd '/usr/local/share/man/man3' && umask 022 && tar xof -)

location

[!NOTE|label:locations]

SCOPEWINDOWSUNIX-LIKE

system

<GIT_DIR>\etc\gitconfig

<GIT_DIR>/etc/gitconfig

system example

%LOCALAPPDATA%\Programs\Git\etc\gitconfig

/usr/local/etc/gitconfig

global

%USERPROFILE%\.gitconfig

$HOME/.gitconfig

local

<git-repo>\.git\config

<git-repo>/.git/config

portable

%PROGRAMDATA%\Git\config

-

get locations

  • windows

      > git config --list --show-origin --name-only | sed -r 's/^file:(.+)\s+.*$/\1/g' | sort.exe /unique
      REM or
      > git config --list --show-origin --name-only | sed -r 's/^file:(.+)\s+.*$/\1/g' | powershell -nop "$input | sort -unique"
      REM or
      > git config --list --show-origin --name-only | sed -r 's/^file:(.+)\s+.*$/\1/g' | powershell -nop "$input | Sort-Object -unique"
      .git/config
      C:/Users/marslo/.gitconfig
      C:/Users/marslo/AppData/Local/Programs/Git/etc/gitconfig
  • osx

    $ git config --list --show-origin --name-only | awk -F'[:[:blank:]]' '{print $2}' | sort -u
    .git/config
    /Users/marslo/.gitconfig
    /Users/marslo/.marslo/.gitalias
    /usr/local/etc/gitconfig
  • edit config file

    $ git config --edit --system
    $ git config --edit --global
    
    # or
    $ sudo git -c core.editor=ls\ -al config --system --edit

list

  • list all with scope

    $ git config --list --show-scope
    system  credential.helper=osxkeychain
    system  core.ignorecase=false
    system  filter.lfs.clean=git-lfs clean -- %f
  • list origin

    $ git config --list --show-origin --show-scope
    system  file:/usr/local/etc/gitconfig credential.helper=osxkeychain
    system  file:/usr/local/etc/gitconfig core.ignorecase=false
    system  file:/usr/local/etc/gitconfig filter.lfs.clean=git-lfs clean -- %f
  • list single scope only

    • list local only

      $ git config --list --local
      core.repositoryformatversion=0
      core.filemode=true
      core.bare=false
    • list global

      $ git config --list --global
      user.name=marslo
      user.email=marslo@gmail.com
      push.default=matching
    • list system

      $ git config --list --system
      credential.helper=osxkeychain
      core.ignorecase=false
      filter.lfs.clean=git-lfs clean -- %f
      filter.lfs.smudge=git-lfs smudge -- %f
      filter.lfs.process=git-lfs filter-process
      filter.lfs.required=true

get from all configure

$ git config --show-origin --show-scope --get-all user.name
global   file:/Users/marslo/.gitconfig   marslo
local    file:.git/config    marslo

colors

[!NOTE|label:references:]

  • configure:

    [!NOTE|label:references:]

    • color.branch.<slot>:

      • current, local, remote, upstream, plain

    • color.diff.<slot>:

      • context, meta, frag, old, new, plain, commit, whitespace,

      • oldMoved, newMoved, oldMovedDimmed, newMovedDimmed, oldMovedAlternative, newMovedAlternative, oldMovedAlternativeDimmed, newMovedAlternativeDimmed

      • contextDimmed, oldDimmed, newDimmed, contextBold, oldBold, newBold

    • color.decorate.<slot>:

      • branch, remoteBranch, tag, stash, HEAD

    • color.grep.<slot>

      • context, filename, function, lineNumber, match, matchContext, matchSelected, selected, separator

    • color.interactive.<slot>:

      • prompt, header, help, error

    • color.status.<slot>:

      • added, updated, changed, untracked, branch, nobranch, localBranch, remoteBranch, unmerged

    • color.remote.<slot>:

      • hint, warning, success, error

  • list color.* config

    $ git config --get-regexp color.*
  • test colors

    [!TIP|label:see also:]

    $ echo $(git config --get-color "" "120 bold reverse") color test $(git config --get-color "" reset)
    
    # i.e.:
    #                                    ╭─ 256 color code
    #                                   ---
    $ echo $(git config --get-color "" "120 bold italic") color test $(git config --get-color "" reset)| command cat -A
    ^[[1;3;38;5;120m color test ^[[m$
    #           ---
    #            ╰─ 256 color code
    
    # with 24bit hex
    #                                    ╭─ R(decimal): 104 : `$ echo -n "obase=10;ibase=16; 68" | bc`
    #                                    --╭─ G(decimal): 157: `$ echo -n "obase=10;ibase=16; 9D" | bc`
    #                                      --╭─ B(decimal): 106: `$ echo -n "obase=10;ibase=16; 6A" | bc`
    #                                        --
    $ echo $(git config --get-color "" "#689d6a italic") color test $(git config --get-color "" reset) | command cat -A
    ^[[3;38;2;104;157;106m color test ^[[m$
    #  -      --- --- ---
    #  ╵       R   G   B
    #  ╰─ SGR (Select Graphic Rendition) parameters ( https://en.wikipedia.org/wiki/ANSI_escape_code ):
    #         0 reset/normal; 1 bold; 2 dim/faint; 3 italic; 4 underline; 5 blink; 7 reverse; 8 hidden
    
    # [or](https://stackoverflow.com/a/18304605/2940319)
    $ remote_branch_color="$(git config --get-color color.branch.remote white)"
    $ echo "pushing to ${remote_branch_color} <branch name here> $(tput sgr0)"
    $ echo "pushing to ${remote_branch_color} <branch name here> $(tput sgr0)" | command cat -A
    pushing to ^[[2;3;38;5;213m <branch name here> ^[(B^[[m$
  • trueHexPrint()

    trueHexPrint () {
      # Generates Truecolor Escape Sequences from Hex Strings. (remove '\\' to use)
      # -fg     Prints as a foreground color. (default)
      # -bg     Prints as a background color.
      # usage) `trueHexPrint -fg "11001A" ==> '\e[38;2;17;0;26m'
      # usage) `trueHexPrint -bg "11001A" ==> '\e[48;2;17;0;26m'
      if [[ ${1} =~ "-fg" || ${1} =~ "-f" ]]; then
        fgbg=38; hexinput=${2};
      elif [[ ${1} =~ "-bg" || ${1} =~ "-b" ]]; then
        fgbg=48; hexinput=${2};
      else
        fgbg=38; hexinput=${1}
      fi
      hexinput=`echo ${hexinput} | tr '[:lower:]' '[:upper:]'`  # uppercase-ing
      hexinput=`echo ${hexinput} | tr -d '#'`               # remove Hash if needed
      a=`echo ${hexinput} | cut -c-2`
      b=`echo ${hexinput} | cut -c3-4`
      c=`echo ${hexinput} | cut -c5-6`
      r=`echo "ibase=16; ${a}" | bc`
      g=`echo "ibase=16; ${b}" | bc`
      b=`echo "ibase=16; ${c}" | bc`
      printf "\\\\e[${fgbg};2;${r};${g};${b}m" # Remove one set of '\\' to utilize
    }
    
    $ trueHexPrint "#689d6a"
    \e[38;2;104;157;106m
    $ echo -e "$(trueHexPrint "#689d6a") aa \e[0m"
     aa

gitconfig

help

  • autocorrect

    [!NOTE|label:references:]

    $ git config --global help.autocorrect immediate
    
    # [y/N] ?
    $ git config --global help.autocorrect prompt
    
    # 2.0 seconds
    $ git config --global help.autocorrect 20

credential

[!NOTE]

$ git config credential.helper store

# or
git remote set-url origin https://[TOKEN]@github.com/path/to/repo.git

environment failed to $ ssh -vT git@github.com -p 22

  1. using https instead of ssh first

    $ cat ~/.gitconfig
    [url "https://github.com/"]
      insteadOf     = git@ssh.github.com:
    [url "https://github.com/"]
      insteadOf     = git@github.com:
  2. setup credential

    $ git config --global credential.helper store
    
    # or set the credential file in corss-platform
    $ git config --global credential.helper 'store --file /path/to/.git-credentials'
    $ git config --global credential.helper 'cache --timeout 30000'
  3. create the credential file

    $ git credential-store --file /path/to/.git-credentials store
    protocol=https 
    host=github.com 
    username=marslo 
    password=ghp_***********************************N 
    
    
    # or
    $ USERNAME='marslo'
    $ PASSWORD='ghp_***********************************N'
    $ echo -e "protocol=https\nhost=github.com\nusername=${USERNAME}\npassword=${PASSWORD}\n" |
           git credential-store --file /path/to/.git-credentials store
    • to read the credentials file

      $ git credential-store --file /path/to/.git-credentials get
      protocol=https 
      host=github.com 
      
      # wil shows:
      username=marslo
      password=ghp_***********************************N
      
      # or
      $ echo -e 'protocol=https\nhost=github.com' |
             git credential-store --file /path/to/.git-credentials get
      username=marslo
      password=ghp_***********************************N

with GIT_USERNAME and GIT_ASKPASS

[!NOTE|label:references:]

  • via config

    [url "https://github.com/username"]
      insteadOf         = git@github.com:username
    [credential "https://github.com/marslo"]
      username          = marslo
    [credential "https://github.com/username"]
      username          = marslojiao-mvl
      helper            = "!f() { test \"$1\" = get && echo \"password=gh************************************vr\"; }; f"
  • via environment

    [!TIP]

    • GIT_ASKPASS must be a executable script

    $ export GIT_ASKPASS="$HOME/.git.askpass.sh"
    # or
    $ git config --global core.askPass "$HOME/.git.askpass.sh"
    # or using in runtime
    $ git -c core.askPass="$HOME/.git.askpass.sh" clone ...
    
    $ cat ~/.git.askpass.sh
    declare repoUrl="$(git remote get-url origin)"
    declare pattern='.+github.com[:/]marslo/.+'
    
    if [[ "${repoUrl}" =~ 'path/to/specific' ]]; then
      echo 'gh************************************vr'
    elif [[ "${repoUrl}" =~ ${pattern} ]]; then
      echo 'gh************************************mx'
    fi
    $ chmod +x ~/.git.askpass.sh
    • GitUsernamePasswordBinding solution | JENKINS-56897

      GIT_ASKPASS=$(mktemp) && chmod a+rx $GIT_ASKPASS && export GIT_ASKPASS
      cat > $GIT_ASKPASS <<< '#!/bin/bash
      case "$1" in
          Username*) exec echo "$JENKINS_CREDENTIALS_USR" ;;
          Password*) exec echo "$JENKINS_CREDENTIALS_PSW" ;;
      esac
      '

default configuration

  • core.editor

    • use vim ( the ubiqutos text editor ) as Git's default editor

      $ git config --get core.editor
      vim
  • init.defaultBranch

    • override the default branch name for new repositories

      $ git config --get init.defaultBranch
      development
  • core.autocrlf

    [!TIP|label:see also:]

    • checkout windows-style, commit unix-style line endings

      $ git config --get core.autocrlf
      true
    • checkout as-is, commit unix-style line endings

      $ git config --get core.autocrlf
      input
    • checkout as-is, commit as-is

      $ git config --get core.autocrlf
      false
  • pull.rebase

    $ git config --get pull.rebase
    true
  • core.fscache & core.symlinks

    • enable file system caching

      $ git config --get core.fscache
      true
    • enable symbolic links

      $ git config --get core.symlinks
      true
  • core.fsmonitor

    • enable experimental built-in file system monitor

      $ git config --get core.fsmonitor
      true

__git_ps1

[!NOTE|label:localtion]

  • osx: $(brew --prefix git)/etc/bash_completion.d/git-prompt.sh

add to bash_completion.d

# if necessary
$ ln -sf "$(brew --prefix git)"/etc/bash_completion.d/git-prompt.sh "$(brew --prefix)"/etc/bash_completion.d/

tig

[!NOTE|label:references:]

# ubuntu
$ sudo apt-get install libncursesw5-dev
# centos/rhel
$ sudo yum install ncurses-devel

$ git clone git@github.com:jonas/tig.git ${iRCHOME}/utils/ && cd !$/tig
$ make -j prefix=/usr/local
$ sudo make install prefix=/usr/local

$ /usr/local/bin/tig --version
tig version 2.5.8-5-g1894954
ncursesw version 6.3.20211021

$ git clone git@github.com:jonas/tig.git && cd tig

$ make
# or
$ make prefix=/usr/local

$ make install
# or
$ sudo make install prefix=/usr/local

$ sudo make install-doc
   INSTALL  doc/tig.1 -> /root/share/man/man1
   INSTALL  doc/tigrc.5 -> /root/share/man/man5
   INSTALL  doc/tigmanual.7 -> /root/share/man/man7
   INSTALL  doc/tig.1.html -> /root/share/doc/tig
   INSTALL  doc/tigrc.5.html -> /root/share/doc/tig
   INSTALL  doc/manual.html -> /root/share/doc/tig
   INSTALL  README.html -> /root/share/doc/tig
   INSTALL  INSTALL.html -> /root/share/doc/tig
   INSTALL  NEWS.html -> /root/share/doc/tig

# or
$ [sudo] make install-release-doc
GIT_INDEX_FILE=.tmp-doc-index git read-tree origin/release
GIT_INDEX_FILE=.tmp-doc-index git checkout-index -f --prefix=./ doc/tig.1 doc/tigrc.5 doc/tigmanual.7
rm -f .tmp-doc-index
make install-doc-man
make[1]: Entering directory '/home/marslo/iMarslo/tools/git/tools/tig'
   INSTALL  doc/tig.1 -> /home/marslo/share/man/man1
   INSTALL  doc/tigrc.5 -> /home/marslo/share/man/man5
   INSTALL  doc/tigmanual.7 -> /home/marslo/share/man/man7
make[1]: Leaving directory '/home/marslo/iMarslo/tools/git/tools/tig'
GIT_INDEX_FILE=.tmp-doc-index git read-tree origin/release
GIT_INDEX_FILE=.tmp-doc-index git checkout-index -f --prefix=./ doc/tig.1.html doc/tigrc.5.html doc/manual.html README.html INSTALL.html NEWS.html
rm -f .tmp-doc-index
make install-doc-html
make[1]: Entering directory '/home/marslo/iMarslo/tools/git/tools/tig'
       GEN  doc/manual.toc
  ASCIIDOC  doc/manual.html
   INSTALL  doc/tig.1.html -> /home/marslo/share/doc/tig
   INSTALL  doc/tigrc.5.html -> /home/marslo/share/doc/tig
   INSTALL  doc/manual.html -> /home/marslo/share/doc/tig
   INSTALL  README.html -> /home/marslo/share/doc/tig
   INSTALL  INSTALL.html -> /home/marslo/share/doc/tig
   INSTALL  NEWS.html -> /home/marslo/share/doc/tig
make[1]: Leaving directory '/home/marslo/iMarslo/tools/git/tools/tig'
  • result

    $ which -a tig
    /usr/local/bin/tig
    
    $ tig --version
    tig version 2.5.8-17-ge543cfe
    ncursesw version 6.1.20180224

troubleshooting

[!TIP]

ld: archive member '/' not a mach-o file

[!NOTE]

  • xCode

    $ xcodebuild -version
    Xcode 15.0
    Build version 15A240d
    $ pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version
    version: 15.1.0.0.1.1700200546
    
    # after upgraded
    $ xcodebuild -version
    Xcode 15.2
    Build version 15C500b
    $ pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version
    version: 15.1.0.0.1.1700200546

Last updated