├── .bookignore ├── .github └── workflows │ ├── linux.yml │ └── macos.yml ├── .gitignore ├── .mailmap ├── COPYING ├── INSTALL.adoc ├── Makefile ├── NEWS.adoc ├── README.adoc ├── appveyor.yml ├── autogen.sh ├── book.json ├── book.md ├── compat ├── ansidecl.h ├── compat.h ├── hashtab.c ├── hashtab.h ├── mkstemps.c ├── setenv.c ├── strndup.c ├── utf8proc.c ├── utf8proc.h ├── utf8proc.license.md ├── utf8proc_data.c └── wordexp.c ├── config.make.in ├── configure.ac ├── contrib ├── bindings-v1.x.tigrc ├── chocolate.theme.tigrc ├── config.make ├── config.make-CYGWIN_NT-6.1 ├── config.make-Darwin ├── config.make-Linux ├── git-flow.tigrc ├── large-repo.tigrc ├── tig-completion.bash ├── tig-completion.zsh ├── tig-pick ├── tig.spec.in └── vim.tigrc ├── doc ├── asciidoc.conf ├── manual.adoc ├── tig.1.adoc ├── tigmanual.7.adoc └── tigrc.5.adoc ├── include └── tig │ ├── apps.h │ ├── argv.h │ ├── blame.h │ ├── blob.h │ ├── diff.h │ ├── display.h │ ├── draw.h │ ├── git.h │ ├── graph.h │ ├── grep.h │ ├── help.h │ ├── io.h │ ├── keys.h │ ├── line.h │ ├── log.h │ ├── main.h │ ├── map.h │ ├── options.h │ ├── pager.h │ ├── parse.h │ ├── prompt.h │ ├── refdb.h │ ├── reflog.h │ ├── refs.h │ ├── repo.h │ ├── request.h │ ├── search.h │ ├── stage.h │ ├── stash.h │ ├── status.h │ ├── string.h │ ├── tig.h │ ├── tree.h │ ├── types.h │ ├── ui.h │ ├── util.h │ ├── view.h │ └── watch.h ├── snap └── snapcraft.yaml ├── src ├── apps.c ├── argv.c ├── blame.c ├── blob.c ├── diff.c ├── display.c ├── draw.c ├── graph-v1.c ├── graph-v2.c ├── graph.c ├── grep.c ├── help.c ├── io.c ├── keys.c ├── line.c ├── log.c ├── main.c ├── map.c ├── options.c ├── pager.c ├── parse.c ├── prompt.c ├── refdb.c ├── reflog.c ├── refs.c ├── repo.c ├── request.c ├── search.c ├── stage.c ├── stash.c ├── status.c ├── string.c ├── tig.c ├── tree.c ├── types.c ├── ui.c ├── util.c ├── view.c └── watch.c ├── test ├── API.adoc ├── README.adoc ├── blame │ ├── blob-blame-test │ ├── default-test │ ├── initial-diff-test │ ├── navigation-parent-test │ ├── revargs-test │ ├── start-on-line-test │ └── stash-test ├── blob │ └── wrap-lines-test ├── diff │ ├── diff-context-test │ ├── diff-highlight-color-test │ ├── diff-highlight-test │ ├── diff-stat-split-test │ ├── diff-stat-test │ ├── diff-stdin-test │ ├── diff-wdiff-context-test │ ├── editor-test │ ├── line-number-test │ ├── maximized-navigation-test │ ├── open-after-split-test │ ├── start-on-line-test │ ├── submodule-editor-diffstat-test │ ├── submodule-editor-test │ ├── worktree-editor-test │ └── wrap-lines-test ├── files │ ├── refs-repo.tgz │ ├── repo-authornamechange.tgz │ ├── repo-one.tgz │ ├── repo-two.tgz │ └── scala-js-benchmarks.tgz ├── graph │ ├── 00-simple-test │ ├── 01-merge-from-left-test │ ├── 02-duplicate-parent-test │ ├── 03-octo-merge-test │ ├── 04-missing-bar-test │ ├── 05-extra-pipe-test │ ├── 06-extra-bars-test │ ├── 07-multi-collapse-test │ ├── 08-multi-collapse-2-test │ ├── 09-parallel-siblings-test │ ├── 10-shorter-merge-than-branch-test │ ├── 11-new-branch-in-middle-test │ ├── 12-cross-over-collapse-test │ ├── 13-collapse-parallel-branches-with-different-middle-branch-test │ ├── 14-long-collapse-line-test │ ├── 15-many-merges-test │ ├── 16-changes-test │ ├── 17-more-merges-test │ ├── 18-tig-test │ ├── 19-tig-all-test │ ├── 20-tig-all-long-test │ ├── 20-tig-all-long-test.in │ ├── gh-490-heap-buffer-overflow-test │ ├── gh-490-heap-buffer-overflow-test.gz │ └── regression │ │ ├── horizontal-artifact-test │ │ └── horizontal-bar-wrong-2-test ├── grep │ ├── default-test │ ├── editor-test │ └── start-on-line-test ├── help │ ├── all-keybindings-test │ ├── all-keybindings-test.expected │ ├── default-test │ └── user-command-test ├── log │ ├── diff-stat-test │ ├── log-graph-test │ ├── pretty-format-test │ ├── start-on-line-test │ └── submodule-test ├── main │ ├── all-arg-test │ ├── author-name-change-test │ ├── boundary-test │ ├── branch-var-test │ ├── commit-order-edge-case-test │ ├── commit-order-edge-case-test.tgz │ ├── commit-title-overflow-test │ ├── date-test │ ├── date-test.in │ ├── default-test │ ├── emoji-test │ ├── escape-control-characters-test │ ├── escape-control-characters-test.in │ ├── filter-args-test │ ├── git-alias-test │ ├── goto-test │ ├── graph-argument-test │ ├── jump-ends-test │ ├── mailmap-test │ ├── main-options-test │ ├── merge-test │ ├── no-matching-commmits-test │ ├── no-merges-test │ ├── pretty-raw-test │ ├── refresh-periodic-test │ ├── refresh-test │ ├── search-preload-test │ ├── search-test │ ├── show-changes-after-rename-test │ ├── show-changes-test │ ├── start-on-line-test │ ├── stdin-test │ ├── submodule-test │ ├── unbind-default-quit-key-test │ ├── untracked-test │ ├── update-unstaged-changes-test │ ├── util.sh │ ├── vertical-lines-test │ └── view-split-test ├── prompt │ └── exec-test ├── reflog │ └── default-test ├── refs │ ├── branch-checkout-test │ ├── branch-tag-test │ ├── branch-var-test │ ├── default-test │ ├── filter-test │ ├── refresh-test │ ├── replace-test │ ├── start-on-line-test │ └── worktree-test ├── regressions │ ├── github-1136-test │ ├── github-370-test │ ├── github-390-test │ └── github-434-test ├── script │ ├── comment-test │ └── default-test ├── stage │ ├── default-test │ ├── gh-410-test │ ├── maximized-unstaged-changes-test │ ├── split-chunk-test │ └── update-part-test ├── stash │ └── start-on-line-test ├── status │ ├── file-name-test │ ├── file-var-test │ ├── on-branch-test │ ├── on-branch-tracking-info-test │ ├── refresh-test │ ├── repo-var-test │ ├── start-on-line-test │ ├── submodule-editor-test │ ├── untracked-files-test │ ├── worktree-editor-test │ └── worktree-test ├── tigrc │ ├── builtin-error-test │ ├── builtin-save-test │ ├── command-value-long-test │ ├── compat-error-test │ ├── contrib-tigrc-test │ ├── env-vars-test │ ├── escape-var-test │ ├── parse-test │ ├── quote-test │ ├── save-option-test │ ├── source-test │ ├── tigrc-manpage-examples-test │ ├── truncation-test │ ├── view-column-test │ ├── width-test │ └── xdg-config-home-test ├── tools │ ├── libgit.sh │ ├── libtest.sh │ ├── setup-conflict.sh │ ├── show-results.sh │ ├── test-graph.c │ └── valgrind-Darwin.supp └── tree │ ├── chdir-test │ ├── default-test │ ├── file-name-test │ ├── submodule-editor-test │ └── worktree-editor-test ├── tigrc └── tools ├── announcement.sh ├── aspell.dict ├── ax_lib_readline.m4 ├── ax_require_defined.m4 ├── ax_with_curses.m4 ├── doc-gen.c ├── gcov.m4 ├── header.h ├── iconv.m4 ├── install.sh ├── make-builtin-config.sh ├── release.sh ├── travis.sh └── uninstall.sh /.bookignore: -------------------------------------------------------------------------------- 1 | # Blacklist most files since documentation is co-located with the rest 2 | # of the source to avoid that GitBook copies them to the output 3 | # directory. 4 | *.* 5 | *-* 6 | COPYING 7 | Makefile 8 | tigrc 9 | 10 | ## Whitelist AsciiDoc and GitBook files 11 | !*.adoc 12 | !*.md 13 | !*.json 14 | 15 | # ... except the manual man-page 16 | doc/tigmanual.7.adoc 17 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ci: 7 | runs-on: ubuntu-latest 8 | 9 | strategy: 10 | matrix: 11 | compiler: [clang, gcc] 12 | tig_build: [autoconf, "config.make"] 13 | include: 14 | - name: Address Sanitizer 15 | compiler: clang 16 | tig_build: "address-sanitizer" 17 | 18 | - name: Valgrind 19 | compiler: gcc 20 | tig_build: valgrind 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Test Tig 25 | shell: 'script -q -e -c "sh {0}"' # Workaround to get a TTY, see https://github.com/gfx/example-github-actions-with-tty 26 | run: | 27 | set -ex 28 | export LANG=en_US.utf8 29 | sudo apt update 30 | sudo DEBIAN_FRONTEND=noninteractive apt -yq install --no-install-recommends \ 31 | asciidoc valgrind xmlto 32 | CC=${{ matrix.compiler }} TIG_BUILD=${{ matrix.tig_build }} tools/travis.sh 33 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: macOS 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | install: 7 | runs-on: macos-latest 8 | if: github.ref == 'refs/heads/master' 9 | 10 | strategy: 11 | matrix: 12 | compiler: [clang, gcc] 13 | 14 | steps: 15 | - name: Patch 16 | run: | 17 | brew tap homebrew/core 18 | cd "$(brew --repo homebrew/core)" && patch -p1 <<\EOF 19 | diff --git a/Formula/t/tig.rb b/Formula/t/tig.rb 20 | index c726e53c519..920b0fbc1c2 100644 21 | --- a/Formula/t/tig.rb 22 | +++ b/Formula/t/tig.rb 23 | @@ -31,9 +31,11 @@ class Tig < Formula 24 | depends_on "readline" 25 | 26 | def install 27 | + ENV.deparallelize 28 | system "./autogen.sh" if build.head? 29 | system "./configure", "--prefix=#{prefix}", "--sysconfdir=#{etc}" 30 | system "make" 31 | + system "make", "test" 32 | # Ensure the configured `sysconfdir` is used during runtime by 33 | # installing in a separate step. 34 | system "make", "install", "sysconfdir=#{pkgshare}/examples" 35 | EOF 36 | - name: Install latest Tig 37 | shell: 'script -q typescript sh {0}' # Workaround to get a TTY, see https://github.com/gfx/example-github-actions-with-tty 38 | run: HOMEBREW_NO_INSTALL_FROM_API=1 HOMEBREW_CC=${{ matrix.compiler }} HOMEBREW_NO_AUTO_UPDATE=1 brew install --HEAD tig 39 | 40 | ci: 41 | runs-on: macos-latest 42 | if: github.ref != 'refs/heads/master' 43 | 44 | steps: 45 | - uses: actions/checkout@v4 46 | - name: Test Tig 47 | shell: 'script -q typescript sh {0}' # Workaround to get a TTY, see https://github.com/gfx/example-github-actions-with-tty 48 | run: | 49 | brew install asciidoc autoconf automake coreutils gnu-sed ncurses xmlto 50 | TIG_BUILD=autoconf tools/travis.sh 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gcno 2 | *.gcda 3 | *.html 4 | *.o 5 | *.swp 6 | *~ 7 | .deps 8 | /_book 9 | /config.make 10 | /node_modules/ 11 | aclocal.m4 12 | autom4te.cache 13 | /compile_commands/ 14 | /compile_commands.json 15 | config.h 16 | config.h.in 17 | config.log 18 | config.status 19 | configure 20 | cscope.out 21 | ctags 22 | doc/*.[157] 23 | doc/*.xml 24 | doc/manual.html-chunked 25 | doc/manual.pdf 26 | doc/manual.toc 27 | doc/release-docs/ 28 | src/builtin-config.c 29 | src/tig 30 | tags 31 | test/coverage 32 | test/tools/test-graph 33 | test/tmp 34 | tig-*.tar.gz 35 | tig-*.tar.gz.sha256 36 | tig.spec 37 | tools/doc-gen 38 | tig.dSYM 39 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Jonas Fonseca 2 | Jonas Fonseca 3 | Jonas Fonseca 4 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | Tig: text-mode interface for Git 2 | ================================ 3 | :docext: adoc 4 | 5 | image:https://github.com/jonas/tig/workflows/Linux/badge.svg[Linux CI,link=https://github.com/jonas/tig/actions?query=workflow%3ALinux] 6 | image:https://github.com/jonas/tig/workflows/macOS/badge.svg[macOS CI,link=https://github.com/jonas/tig/actions?query=workflow%3AmacOS] 7 | image:https://ci.appveyor.com/api/projects/status/jxt1uf52o7r0a8r7/branch/master?svg=true[AppVeyor Build,link=https://ci.appveyor.com/project/fonseca/tig] 8 | image:https://badges.gitter.im/Join%20Chat.svg[Join Chat,link="https://gitter.im/jonas/tig?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"] 9 | 10 | What is Tig? 11 | ------------ 12 | Tig is an ncurses-based text-mode interface for git. It functions mainly 13 | as a Git repository browser, but can also assist in staging changes for 14 | commit at chunk level and act as a pager for output from various Git 15 | commands. 16 | 17 | Resources 18 | --------- 19 | 20 | - Homepage: https://github.com/jonas/tig[] 21 | - Manual: https://github.com/jonas/tig/blob/master/doc/manual.adoc[] 22 | - Tarballs: https://github.com/jonas/tig/releases[] 23 | - Git URL: https://github.com/jonas/tig.git[] 24 | - Gitter: https://gitter.im/jonas/tig[] 25 | - Q&A: https://stackoverflow.com/questions/tagged/tig[] 26 | 27 | Bugs and Feature Requests 28 | ------------------------- 29 | Bugs and feature requests can be reported using the 30 | https://github.com/jonas/tig/issues[issue tracker] or by mail to the 31 | https://lore.kernel.org/git/[Git mailing list]. Ensure that the word 32 | "tig" is in the subject. For other Tig related questions please use 33 | Stack Overflow: https://stackoverflow.com/questions/tagged/tig[]. 34 | 35 | If you are sending a bug report, please include the following information: 36 | 37 | - What Tig and ncurses versions are you using? 38 | (`tig -v`) 39 | - What system do you have? 40 | (`uname -a`, `lsb_release -a`) 41 | - What Git version are you using? 42 | (`git -v`) 43 | 44 | Installation and News 45 | --------------------- 46 | 47 | Information on how to build and install Tig are found in 48 | link:INSTALL.{docext}[the installation instructions]. 49 | 50 | News about releases and latest features and bug fixes are found in 51 | link:NEWS.{docext}[the release notes]. 52 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - TARGET: cygwin64 4 | ARCH: x86_64 5 | 6 | install: 7 | - appveyor DownloadFile https://cygwin.com/setup-%ARCH%.exe -FileName C:\%TARGET%\setup-%ARCH%.exe 8 | - cmd: C:\%TARGET%\setup-%ARCH%.exe -qgnNdO -l C:\%TARGET%\var\cache\setup -R C:\%TARGET% -s https://cygwin.mirror.constant.com -P git -P gcc-code -P make -P automake -P libiconv-devel -P libncurses-devel 9 | - cmd: SET PATH=C:\%TARGET%\bin;%PATH% 10 | - git config --global --add safe.directory /cygdrive/c/projects/tig 11 | 12 | build_script: 13 | - make configure 14 | - sh configure 15 | - make 16 | 17 | test_script: 18 | - make test 19 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export WARNINGS="all" 4 | set -e 5 | 6 | # Ideally, we could just do this: 7 | # 8 | #${AUTORECONF:-autoreconf} -v -I tools 9 | # 10 | # Unfortunately, Autoconf 2.61's autoreconf(1) (found in Mac OS X 10.5 11 | # Leopard) neglects to pass the -I on to aclocal(1), which is 12 | # precisely where we need it! So we do basically what it would have 13 | # done. 14 | 15 | run () { 16 | test "${V}" = 1 && echo $0: running: "$@" 17 | "$@" 18 | } 19 | 20 | run ${ACLOCAL:-aclocal} -I tools 21 | run ${AUTOCONF:-autoconf} --include=tools 22 | run ${AUTOHEADER:-autoheader} --include=tools 23 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "gitbook": "3.2.x", 3 | "title": "Tig - Text-mode interface for Git", 4 | "structure": { 5 | "readme": "README.adoc", 6 | "summary": "book.md" 7 | }, 8 | "links": { 9 | "sharing": { 10 | "twitter": false, 11 | "facebook": false, 12 | "google": false, 13 | "all": false 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /book.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Installation](INSTALL.adoc) 4 | - [Release notes](NEWS.adoc) 5 | - [tig(1)](doc/tig.1.adoc) 6 | - [tigrc(5)](doc/tigrc.5.adoc) 7 | - [Manual](doc/manual.adoc) 8 | - [Screenshots](https://www.flickr.com/photos/jonasfonseca/albums/72157614470764617) 9 | - Developer Documentation 10 | - [Testing](test/README.adoc) 11 | -------------------------------------------------------------------------------- /compat/compat.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * Copyright (c) 2013 Drew Northup 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License as 6 | * published by the Free Software Foundation; either version 2 of 7 | * the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | */ 14 | 15 | #ifndef TIG_COMPAT_H 16 | #define TIG_COMPAT_H 17 | 18 | #ifndef HAVE_CONFIG_H 19 | /* 20 | * Enable inclusion of header files checked by configure. 21 | */ 22 | #define HAVE_STDINT_H 23 | #define HAVE_STDLIB_H 24 | #define HAVE_STRING_H 25 | #define HAVE_SYS_TIME_H 26 | #define HAVE_UNISTD_H 27 | #define HAVE_WORDEXP_H 28 | #endif 29 | 30 | /* 31 | * XXX: Compatibility code must never be enabled by default. 32 | */ 33 | 34 | #ifdef NO_MKSTEMPS 35 | #define mkstemps compat_mkstemps 36 | int compat_mkstemps(char *pattern, int suffix_len); 37 | #endif 38 | 39 | #ifdef NO_SETENV 40 | #define setenv compat_setenv 41 | int compat_setenv(const char *name, const char *value, int replace); 42 | #endif 43 | 44 | #ifdef NO_STRNDUP 45 | #include 46 | #define strndup compat_strndup 47 | char *compat_strndup(const char *s, size_t n); 48 | #endif 49 | 50 | #ifdef NO_WORDEXP 51 | #define wordexp compat_wordexp 52 | #define wordfree compat_wordfree 53 | #define WRDE_NOCMD 4 54 | typedef struct 55 | { 56 | char **we_wordv; 57 | } wordexp_t; 58 | int compat_wordexp (const char *words, wordexp_t *pwordexp, int flags); 59 | void compat_wordfree (wordexp_t *pwordexp); 60 | #else 61 | #include 62 | #endif 63 | 64 | #endif 65 | 66 | /* vim: set ts=8 sw=8 noexpandtab: */ 67 | -------------------------------------------------------------------------------- /compat/strndup.c: -------------------------------------------------------------------------------- 1 | /* Implement the strndup function. 2 | Copyright (C) 2005 Free Software Foundation, Inc. 3 | Written by Kaveh R. Ghazi . 4 | 5 | This file is part of the libiberty library. 6 | Libiberty is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Library General Public 8 | License as published by the Free Software Foundation; either 9 | version 2 of the License, or (at your option) any later version. 10 | 11 | Libiberty is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Library General Public License for more details. 15 | 16 | You should have received a copy of the GNU Library General Public 17 | License along with libiberty; see the file COPYING.LIB. If 18 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 19 | Boston, MA 02110-1301, USA. */ 20 | 21 | /* 22 | * This file was borrowed on 2014-05-05 and adapted from: 23 | * https://raw.github.com/mirrors/gcc/master/libiberty/strndup.c 24 | */ 25 | #ifdef HAVE_CONFIG_H 26 | #include "config.h" 27 | #endif 28 | 29 | #include "compat.h" 30 | 31 | #include 32 | #ifdef HAVE_STDLIB_H 33 | #include 34 | #endif 35 | #ifdef HAVE_STRING_H 36 | #include 37 | #endif 38 | 39 | char * 40 | compat_strndup (const char *s, size_t n) 41 | { 42 | char *result; 43 | size_t len = strlen (s); 44 | 45 | if (n < len) 46 | len = n; 47 | 48 | result = (char *) malloc (len + 1); 49 | if (!result) 50 | return 0; 51 | 52 | result[len] = '\0'; 53 | return (char *) memcpy (result, s, len); 54 | } 55 | -------------------------------------------------------------------------------- /compat/wordexp.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifdef HAVE_CONFIG_H 15 | #include "config.h" 16 | #endif 17 | 18 | #include "compat.h" 19 | #include "stddef.h" 20 | #include 21 | #include 22 | #include 23 | 24 | void 25 | compat_wordfree (wordexp_t *pwordexp) 26 | { 27 | free(pwordexp->we_wordv[0]); 28 | free(pwordexp->we_wordv); 29 | } 30 | 31 | int 32 | compat_wordexp (const char *words, wordexp_t *pwordexp, int flags) 33 | { 34 | char *expanded = NULL; 35 | const char *home = getenv("HOME"); 36 | 37 | if (home && words[0] == '~' && (words[1] == '/' || words[1] == 0)) { 38 | size_t len = strlen(home) + strlen(words + 1) + 1; 39 | if ((expanded = malloc(len)) && !snprintf(expanded, len, "%s%s", home, words + 1)) { 40 | free(expanded); 41 | return -1; 42 | } 43 | } else { 44 | expanded = strdup(words); 45 | } 46 | 47 | if (!expanded) 48 | return -1; 49 | 50 | pwordexp->we_wordv = calloc(2, sizeof(*pwordexp->we_wordv)); 51 | if (!pwordexp->we_wordv) { 52 | free(expanded); 53 | return -1; 54 | } 55 | pwordexp->we_wordv[0] = expanded; 56 | 57 | return 0; 58 | } 59 | 60 | /* vim: set ts=8 sw=8 noexpandtab: */ 61 | -------------------------------------------------------------------------------- /config.make.in: -------------------------------------------------------------------------------- 1 | # -*- makefile-gmake -*- 2 | 3 | prefix = @prefix@ 4 | exec_prefix = @exec_prefix@ 5 | bindir = @bindir@ 6 | mandir = @mandir@ 7 | docdir = @docdir@ 8 | datarootdir = @datarootdir@ 9 | sysconfdir = @sysconfdir@ 10 | 11 | CC = @CC@ 12 | CFLAGS = @CFLAGS@ @COVERAGE_CFLAGS@ 13 | # CURSES_CFLAGS contain `-I..` flags so add to preprocessor flags. 14 | CPPFLAGS = @CPPFLAGS@ @CURSES_CFLAGS@ -DHAVE_CONFIG_H 15 | LDFLAGS = @LDFLAGS@ 16 | LDLIBS = @LIBS@ @CURSES_LIBS@ 17 | 18 | ASCIIDOC = @ASCIIDOC@ 19 | XMLTO = @XMLTO@ 20 | DOCBOOK2PDF = @DOCBOOK2PDF@ 21 | 22 | LCOV = @LCOV@ 23 | GENHTML = @GENHTML@ 24 | 25 | # Special compatibility features 26 | @NO_MKSTEMPS@ NO_MKSTEMPS = y 27 | @NO_SETENV@ NO_SETENV = y 28 | @NO_STRNDUP@ NO_STRNDUP = y 29 | @NO_WORDEXP@ NO_WORDEXP = y 30 | 31 | # Add config.h as a dependency for all object files 32 | CONFIG_H = config.h 33 | 34 | config.status: configure 35 | ./config.status --recheck 36 | 37 | config.h config.make: config.status 38 | ./config.status $@ 39 | 40 | config.make: config.make.in 41 | -------------------------------------------------------------------------------- /contrib/bindings-v1.x.tigrc: -------------------------------------------------------------------------------- 1 | # Bindings from before version 2.0 2 | # 3 | # To use these bindings copy the file to your HOME directory and include 4 | # it from your ~/.tigrc file: 5 | # 6 | # $ cp contrib/bindings-v1.x.tigrc ~/.tigrc.compat 7 | # $ echo "source ~/.tigrc.compat" >> ~/.tigrc 8 | 9 | bind generic B view-blame 10 | bind generic G view-grep 11 | bind generic H view-refs 12 | bind generic S view-status 13 | 14 | bind generic r screen-redraw 15 | bind generic w scroll-page-up 16 | bind generic s scroll-page-down 17 | bind generic b move-page-up 18 | 19 | bind generic g :toggle commit-title-graph 20 | bind generic i :toggle sort-field 21 | bind generic . :toggle line-number 22 | bind generic :toggle file-name 23 | bind generic F :toggle commit-title-refs 24 | -------------------------------------------------------------------------------- /contrib/chocolate.theme.tigrc: -------------------------------------------------------------------------------- 1 | color diff-stat 95 default 2 | color date 172 default 3 | color "Merge: " cyan default 4 | color graph-commit red default 5 | color id 167 default 6 | color "author " 95 default 7 | color "Commit: " 90 default 8 | color cursor white 101 bold 9 | 10 | color palette-0 93 default 11 | color palette-1 95 default 12 | color palette-2 124 default 13 | color palette-7 90 default bold 14 | 15 | color delimiter 90 default 16 | color main-tracked 99 default bold 17 | -------------------------------------------------------------------------------- /contrib/config.make: -------------------------------------------------------------------------------- 1 | # Example config.make. 2 | 3 | # Install files under /usr/local instead of under $HOME. 4 | prefix=/usr/local 5 | 6 | # Use ncursesw. 7 | LDLIBS = -lncursesw 8 | CPPFLAGS = -DHAVE_NCURSESW_CURSES_H 9 | 10 | # Use readline. 11 | #LDLIBS += -lreadline 12 | #CPPFLAGS += -DHAVE_READLINE 13 | 14 | # Use PCRE2. 15 | #LDLIBS += -lpcre2-posix -lpcre2-8 16 | #CPPFLAGS += -DHAVE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8 17 | 18 | # Uncomment to enable work-around for missing setenv(). 19 | #NO_SETENV=y 20 | 21 | # Uncomment to enable work-around for missing mkstemps(). 22 | #NO_MKSTEMPS=y 23 | 24 | # Uncomment to enable work-around for missing wordexp(). 25 | #NO_WORDEXP=y 26 | 27 | # Uncomment to not include built-in tigrc inside the binary. 28 | #NO_BUILTIN_TIGRC=y 29 | 30 | # vim: ft=make: 31 | -------------------------------------------------------------------------------- /contrib/config.make-CYGWIN_NT-6.1: -------------------------------------------------------------------------------- 1 | # Example configuration for Cygwin (`uname -s` = CYGWIN_NT-6.1) 2 | # 3 | # Use ncursesw. 4 | 5 | NCURSESW_LIBS = $(shell ncursesw6-config --libs 2>/dev/null) 6 | HAS_ICONV = $(shell test -e "/usr/include/iconv.h" && echo true) 7 | 8 | ifeq ($(NCURSESW_LIBS),) 9 | $(error Please install the libncursesw-devel package) 10 | endif 11 | 12 | ifneq ($(HAS_ICONV),true) 13 | $(error Please install the libiconv-devel package) 14 | endif 15 | 16 | TIG_NCURSES = $(NCURSESW_LIBS) 17 | TIG_LDLIBS = -liconv 18 | TIG_CPPFLAGS = -DHAVE_NCURSESW_CURSES_H 19 | 20 | # vim: ft=make: 21 | -------------------------------------------------------------------------------- /contrib/config.make-Darwin: -------------------------------------------------------------------------------- 1 | # Example configuration for Darwin / macOS. 2 | 3 | ifeq ($(origin HOMEBREW_PREFIX), undefined) 4 | HOMEBREW_PREFIX := $(shell brew --prefix 2>/dev/null) 5 | endif 6 | 7 | # Work-around for Homebrew-based xmlto. 8 | export XML_CATALOG_FILES=$(HOMEBREW_PREFIX)/etc/xml/catalog 9 | 10 | TIG_CFLAGS += -DHAVE_EXECINFO_H 11 | TIG_LDLIBS = -liconv 12 | 13 | NCURSES_DIR ?= $(wildcard $(HOMEBREW_PREFIX)/opt/ncurses) 14 | 15 | ifneq ($(NCURSES_DIR),) 16 | TIG_NCURSES = -lncursesw 17 | TIG_CPPFLAGS += -I$(NCURSES_DIR)/include -DHAVE_NCURSESW_CURSES_H 18 | TIG_LDFLAGS += -L$(NCURSES_DIR)/lib 19 | else 20 | TIG_CPPFLAGS += -DHAVE_CURSES_H 21 | endif 22 | 23 | READLINE_DIR ?= $(wildcard $(HOMEBREW_PREFIX)/opt/readline) 24 | 25 | ifneq ($(READLINE_DIR),) 26 | TIG_LDLIBS += -lreadline 27 | TIG_LDFLAGS += -L$(READLINE_DIR)/lib 28 | TIG_CPPFLAGS += -I$(READLINE_DIR)/include -DHAVE_READLINE 29 | endif 30 | 31 | PCRE2_DIR ?= $(wildcard $(HOMEBREW_PREFIX)/opt/pcre2) 32 | 33 | ifneq ($(PCRE2_DIR),) 34 | TIG_LDLIBS += -lpcre2-posix -lpcre2-8 35 | TIG_LDFLAGS += -L$(PCRE2_DIR)/lib 36 | TIG_CPPFLAGS += -I$(PCRE2_DIR)/include -DHAVE_PCRE2 -DPCRE2_CODE_UNIT_WIDTH=8 37 | endif 38 | 39 | # vim: ft=make: 40 | -------------------------------------------------------------------------------- /contrib/config.make-Linux: -------------------------------------------------------------------------------- 1 | # Example configuration for Linux. 2 | # 3 | # Use ncursesw. 4 | 5 | TIG_NCURSES = -lncursesw 6 | TIG_CPPFLAGS = -DHAVE_NCURSESW_CURSES_H 7 | 8 | # vim: ft=make: 9 | -------------------------------------------------------------------------------- /contrib/git-flow.tigrc: -------------------------------------------------------------------------------- 1 | # Bindings for git-flow. 2 | # 3 | # Flow bindings start with the capital F and then follow the first character of 4 | # each operation. If executed from the refs view, the operations (that make 5 | # sense to) work on the selected branch. Otherwise, they work on the currently 6 | # checked out branch. 7 | # 8 | # Commands that finish a flow require confirmation to run. Commands that create 9 | # a new flow prompt for user input and run when that input is accepted with no 10 | # confirmation prompt. 11 | # 12 | # Note: Bindings assume the standard git-flow paths of feature, release, hotfix 13 | # and support. 14 | # 15 | # To use these keybindings copy the file to your HOME directory and include it 16 | # from your ~/.tigrc file: 17 | # 18 | # $ cp contrib/git-flow.tigrc ~/.tigrc.git-flow 19 | # $ echo "source ~/.tigrc.git-flow" >> ~/.tigrc 20 | 21 | # Get rid of default bindings for F, as that will be the entry point for all 22 | # git-flow related commands with this binding. 23 | bind generic F none 24 | 25 | # General 26 | bind generic Fi ?git flow init 27 | 28 | # Feature 29 | bind generic Ffl !git flow feature 30 | bind generic Ffs !git flow feature start "%(prompt New feature name: )" 31 | bind generic Fff ?sh -c "git flow feature finish `echo %(repo:head) | sed -e s/feature.//`" 32 | bind refs Fff ?sh -c "git flow feature finish `echo %(branch) | sed -e s/feature.//`" 33 | 34 | # Release 35 | bind generic Frl !git flow release 36 | bind generic Frs !git flow release start "%(prompt New release name: )" 37 | bind generic Frf ?sh -c "git flow release finish `echo %(repo:head) | sed -e s/release.//`" 38 | bind refs Frf ?sh -c "git flow release finish `echo %(branch) | sed -e s/release.//`" 39 | 40 | # Hot Fix 41 | bind generic Fhl !git flow hotfix 42 | bind generic Fhs !git flow hotfix start "%(prompt New hotfix name: )" 43 | bind generic Fhf ?sh -c "git flow hotfix finish `echo %(repo:head) | sed -e s/hotfix.//`" 44 | bind refs Fhf ?sh -c "git flow hotfix finish `echo %(branch) | sed -e s/hotfix.//`" 45 | 46 | # Support 47 | bind generic Fsl !git flow support 48 | bind refs Fss !git flow support start "%(prompt New support name: )" %(branch) 49 | -------------------------------------------------------------------------------- /contrib/large-repo.tigrc: -------------------------------------------------------------------------------- 1 | # Settings for speeding up Tig in large repositories 2 | # 3 | # To use these settings copy the file to your HOME directory and include 4 | # it from your ~/.tigrc file: 5 | # 6 | # $ cp contrib/large-repo.tigrc ~/.tigrc.large 7 | # $ echo "source ~/.tigrc.large" >> ~/.tigrc 8 | 9 | # Use Git's default (reverse chronological) order, never automatically 10 | # use topo-order for the commit graph 11 | set commit-order = default 12 | 13 | # Don't show diffstat 14 | set log-options = 15 | 16 | # Limit number of commits loaded by default to 1000 17 | set main-options = -n 1000 18 | 19 | # Don't show staged and unstaged changes in the main view 20 | set show-changes = no 21 | 22 | # Optionally, use the old and faster but less acurate graph renderer 23 | #set main-view-commit-title-graph = v1 24 | -------------------------------------------------------------------------------- /contrib/tig-completion.zsh: -------------------------------------------------------------------------------- 1 | #compdef tig 2 | # 3 | # zsh completion wrapper for tig 4 | # ============================== 5 | # 6 | # You need to install this script to zsh fpath with tig-completion.bash. 7 | # 8 | # The recommended way to install this script is to copy this and tig-completion.bash 9 | # to '~/.zsh/_tig' and '~/.zsh/tig-completion.bash' and 10 | # then add following to your ~/.zshrc file: 11 | # 12 | # fpath=(~/.zsh $fpath) 13 | # 14 | # You also need Git's Zsh completion installed: 15 | # 16 | # https://github.com/felipec/git-completion/blob/master/git-completion.zsh 17 | 18 | 19 | _tig () { 20 | local e 21 | 22 | compdef _git tig 23 | 24 | e=$(dirname ${funcsourcetrace[1]%:*})/tig-completion.bash 25 | if [ -f $e ]; then 26 | # Temporarily override __git_complete so the bash script doesn't complain 27 | local old="$functions[__git_complete]" 28 | functions[__git_complete]=: 29 | . $e 30 | functions[__git_complete]="$old" 31 | fi 32 | } 33 | -------------------------------------------------------------------------------- /contrib/tig-pick: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # 'tig-pick' is a wrapper script that uses 'tig' to pick a Git commit from the 4 | # history. On success, The script prints the ID of the commit to standard 5 | # output, so that it can be used as a parameter for subsequent commands, e.g. 6 | # 'git rebase -i $(tig-pick)' 7 | # 8 | # In order to be able to display the interface and to catch the commit ID 9 | # (easily) at the same time, 'tig' has to be run with the standard and error 10 | # output channels swapped. 11 | # 12 | # All parameters passed to the script will be forwarded to 'tig'. 13 | # 14 | 15 | 16 | set -e 17 | 18 | CONFIG=$(mktemp) 19 | trap "rm -f '$CONFIG'" EXIT 20 | 21 | # Prepare config file: source user config, if present 22 | if [ ! -z "$TIGRC_USER" ]; then 23 | echo "source $TIGRC_USER" >> "$CONFIG" 24 | elif [ -f "$HOME/.tigrc" ]; then 25 | echo "source $HOME/.tigrc" >> "$CONFIG" 26 | fi 27 | 28 | # Bind Enter to print the selected commit ID to error output and exit after 29 | # that. 30 | echo 'bind main &2"' >> "$CONFIG" 31 | 32 | 33 | # Run tig with the standard and error output channels swapped. 34 | export TIGRC_USER=$CONFIG 35 | stderr=$(tig "$@" 3>&2 2>&1 1>&3 3>&-) || { 36 | status=$? 37 | echo "$stderr" >&2 38 | exit $status 39 | } 40 | commit=$(echo "$stderr" | tail -n1) 41 | 42 | # Check return value for valid commit ID 43 | if ! printf '%s' "$commit" | grep -iqE '^[0-9a-f]{40}$'; then 44 | echo "$stderr" >&2 45 | exit 1 46 | fi 47 | 48 | echo "$commit" 49 | -------------------------------------------------------------------------------- /contrib/vim.tigrc: -------------------------------------------------------------------------------- 1 | # Vim-style keybindings for Tig 2 | # 3 | # To use these keybindings copy the file to your HOME directory and include 4 | # it from your ~/.tigrc file: 5 | # 6 | # $ cp contrib/vim.tigrc ~/.tigrc.vim 7 | # $ echo "source ~/.tigrc.vim" >> ~/.tigrc 8 | 9 | bind generic h scroll-left 10 | bind generic j move-down 11 | bind generic k move-up 12 | bind generic l scroll-right 13 | 14 | bind generic g none 15 | bind generic gg move-first-line 16 | bind generic gj next 17 | bind generic gk previous 18 | bind generic gp parent 19 | bind generic gP back 20 | bind generic gn view-next 21 | 22 | bind main G move-last-line 23 | bind generic G move-last-line 24 | 25 | bind generic move-page-down 26 | bind generic move-page-up 27 | 28 | bind generic v none 29 | bind generic vm view-main 30 | bind generic vd view-diff 31 | bind generic vl view-log 32 | bind generic vt view-tree 33 | bind generic vb view-blob 34 | bind generic vx view-blame 35 | bind generic vr view-refs 36 | bind generic vs view-status 37 | bind generic vu view-stage 38 | bind generic vy view-stash 39 | bind generic vg view-grep 40 | bind generic vp view-pager 41 | bind generic vh view-help 42 | 43 | bind generic o none 44 | bind generic oo :toggle sort-order 45 | bind generic os :toggle sort-field 46 | bind generic on :toggle line-number 47 | bind generic od :toggle date 48 | bind generic oa :toggle author 49 | bind generic og :toggle line-graphics 50 | bind generic of :toggle file-name 51 | bind generic op :toggle ignore-space 52 | bind generic oi :toggle id 53 | bind generic ot :toggle commit-title-overflow 54 | bind generic oF :toggle file-filter 55 | bind generic or :toggle commit-title-refs 56 | 57 | bind generic @ none 58 | bind generic @j :/^@@ 59 | bind generic @k :?^@@ 60 | bind generic @- :toggle diff-context -1 61 | bind generic @+ :toggle diff-context +1 62 | 63 | bind generic u none 64 | bind generic uu status-update 65 | bind generic ur status-revert 66 | bind generic um status-merge 67 | bind generic ul stage-update-line 68 | bind generic up stage-update-part 69 | bind generic us stage-split-chunk 70 | 71 | bind generic c none 72 | bind generic cc !git commit 73 | bind generic ca !?@git commit --amend --no-edit 74 | 75 | bind generic K view-help 76 | bind generic view-next 77 | -------------------------------------------------------------------------------- /doc/asciidoc.conf: -------------------------------------------------------------------------------- 1 | [macros] 2 | (?su)[\\]?(?Pmanpage):(?P\S*?)\[(?P.*?)\]= 3 | 4 | ifdef::backend-docbook[] 5 | [manpage-inlinemacro] 6 | {0%{target}} 7 | {0#} 8 | {0#{target}{0}} 9 | {0#} 10 | endif::backend-docbook[] 11 | 12 | ifdef::backend-xhtml11[] 13 | [manpage-inlinemacro] 14 | {target}{0?({0})} 15 | endif::backend-xhtml11[] 16 | 17 | ifdef::doctype-manpage[] 18 | ifdef::backend-docbook[] 19 | [header] 20 | template::[header-declarations] 21 | 22 | 23 | {revdate} 24 | 25 | 26 | {mantitle} 27 | {manvolnum} 28 | Tig 29 | {version} 30 | Tig Manual 31 | 32 | 33 | {manname} 34 | {manpurpose} 35 | 36 | 37 | # The following two small workarounds insert a simple paragraph after screen 38 | # 39 | 40 | [listingblock] 41 | {title} 42 | 43 | | 44 | 45 | {title#} 46 | 47 | [verseblock] 48 | {title} 49 | {title%} 50 | {title#} 51 | | 52 | 53 | {title#} 54 | endif::backend-docbook[] 55 | endif::doctype-manpage[] 56 | 57 | ifdef::readme[] 58 | # No header or footers for README.html 59 | [header] 60 |
61 |

{doctitle}

62 | 63 | [footer] 64 |
65 | 66 | [replacements] 67 | (^|[^-\\])--($|[^-])=\1--\2 68 | endif::readme[] 69 | -------------------------------------------------------------------------------- /doc/tigmanual.7.adoc: -------------------------------------------------------------------------------- 1 | tigmanual(7) 2 | ============ 3 | 4 | NAME 5 | ---- 6 | tigmanual - text-mode interface for Git 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | tig [options] [revisions] [--] [paths] 12 | tig show [options] [revisions] [--] [paths] 13 | tig blame [options] [rev] [--] path 14 | tig status 15 | tig < [Git command output] 16 | 17 | DESCRIPTION 18 | ----------- 19 | 20 | include::manual.adoc[] 21 | -------------------------------------------------------------------------------- /include/tig/apps.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_APPS_H 15 | #define TIG_APPS_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/argv.h" 19 | #include "tig/util.h" 20 | 21 | /* 22 | * general 23 | */ 24 | 25 | struct app_external { 26 | const char *argv[SIZEOF_ARG]; 27 | char * const env[SIZEOF_ARG]; 28 | }; 29 | 30 | /* 31 | * diff-highlight 32 | */ 33 | 34 | struct app_external *app_diff_highlight_load(const char *query); 35 | 36 | #endif 37 | 38 | /* vim: set ts=8 sw=8 noexpandtab: */ 39 | -------------------------------------------------------------------------------- /include/tig/blame.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_BLAME_H 15 | #define TIG_BLAME_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view blame_view; 20 | 21 | static inline void 22 | open_blame_view(struct view *prev, enum open_flags flags) 23 | { 24 | open_view(prev, &blame_view, flags); 25 | } 26 | 27 | #endif 28 | /* vim: set ts=8 sw=8 noexpandtab: */ 29 | -------------------------------------------------------------------------------- /include/tig/blob.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_BLOB_H 15 | #define TIG_BLOB_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view blob_view; 20 | void open_blob_view(struct view *prev, enum open_flags flags); 21 | 22 | #endif 23 | /* vim: set ts=8 sw=8 noexpandtab: */ 24 | -------------------------------------------------------------------------------- /include/tig/diff.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_DIFF_H 15 | #define TIG_DIFF_H 16 | 17 | #include "tig/view.h" 18 | 19 | struct diff_state { 20 | bool after_commit_title; 21 | bool after_diff; 22 | bool reading_diff_chunk; 23 | bool reading_diff_stat; 24 | bool combined_diff; 25 | bool adding_describe_ref; 26 | bool highlight; 27 | bool stage; 28 | unsigned int parents; 29 | const char *file; 30 | unsigned int lineno; 31 | struct position pos; 32 | struct io view_io; 33 | }; 34 | 35 | enum request diff_common_edit(struct view *view, enum request request, struct line *line); 36 | bool diff_common_read(struct view *view, const char *data, struct diff_state *state); 37 | enum request diff_common_enter(struct view *view, enum request request, struct line *line); 38 | struct line *diff_common_add_diff_stat(struct view *view, const char *text, size_t offset); 39 | void diff_common_select(struct view *view, struct line *line, const char *changes_msg); 40 | void diff_save_line(struct view *view, struct diff_state *state, enum open_flags flags); 41 | void diff_restore_line(struct view *view, struct diff_state *state); 42 | enum status_code diff_init_highlight(struct view *view, struct diff_state *state); 43 | bool diff_done_highlight(struct diff_state *state); 44 | 45 | unsigned int diff_get_lineno(struct view *view, struct line *line, bool old); 46 | const char *diff_get_pathname(struct view *view, struct line *line, bool old); 47 | 48 | extern struct view diff_view; 49 | 50 | static inline void 51 | open_diff_view(struct view *prev, enum open_flags flags) 52 | { 53 | open_view(prev, &diff_view, flags); 54 | } 55 | 56 | #endif 57 | /* vim: set ts=8 sw=8 noexpandtab: */ 58 | -------------------------------------------------------------------------------- /include/tig/display.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_DISPLAY_H 15 | #define TIG_DISPLAY_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/keys.h" 19 | 20 | int get_input(int prompt_position, struct key *key); 21 | int get_input_char(void); 22 | 23 | extern WINDOW *status_win; 24 | 25 | void update_status(const char *msg, ...) PRINTF_LIKE(1, 2); 26 | void update_status_with_context(const char *context, const char *msg, ...) PRINTF_LIKE(2, 3); 27 | void report(const char *msg, ...) PRINTF_LIKE(1, 2); 28 | void report_clear(void); 29 | 30 | /* 31 | * Display management. 32 | */ 33 | 34 | /* The display array of active views and the index of the current view. */ 35 | extern struct view *display[2]; 36 | extern unsigned int current_view; 37 | 38 | #define foreach_displayed_view(view, i) \ 39 | for (i = 0; i < ARRAY_SIZE(display) && (view = display[i]); i++) 40 | 41 | #define displayed_views() (!!display[0] + !!display[1]) 42 | 43 | #define view_is_displayed(view) \ 44 | (view == display[0] || view == display[1]) 45 | 46 | void init_tty(void); 47 | void init_display(void); 48 | void resize_display(void); 49 | void redraw_display(bool clear); 50 | bool save_display(const char *path); 51 | bool save_view(struct view *view, const char *path); 52 | 53 | bool vertical_split_is_enabled(enum vertical_split vsplit, int height, int width); 54 | int apply_vertical_split(int base_width); 55 | 56 | bool open_external_viewer(const char *argv[], const char *dir, bool silent, bool confirm, bool echo, bool quick, bool refresh, const char *notice); 57 | void open_editor(const char *file, unsigned int lineno); 58 | void enable_mouse(bool enable); 59 | 60 | enum status_code open_script(const char *path); 61 | bool is_script_executing(void); 62 | 63 | #define get_cursor_pos(cursor_y, cursor_x) getyx(newscr, cursor_y, cursor_x) 64 | #define set_cursor_pos(cursor_y, cursor_x) wmove(newscr, cursor_y, cursor_x) 65 | 66 | #endif 67 | /* vim: set ts=8 sw=8 noexpandtab: */ 68 | -------------------------------------------------------------------------------- /include/tig/draw.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_DRAW_H 15 | #define TIG_DRAW_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/line.h" 19 | #include "tig/view.h" 20 | #include "tig/refdb.h" 21 | #include "tig/util.h" 22 | 23 | enum align { 24 | ALIGN_LEFT, 25 | ALIGN_RIGHT 26 | }; 27 | 28 | bool draw_text(struct view *view, enum line_type type, const char *string); 29 | bool PRINTF_LIKE(3, 4) draw_formatted(struct view *view, enum line_type type, const char *format, ...); 30 | bool draw_graphic(struct view *view, enum line_type type, const chtype graphic[], size_t size, bool separator); 31 | bool draw_field(struct view *view, enum line_type type, const char *text, int width, enum align align, bool trim); 32 | bool draw_lineno(struct view *view, struct view_column *column, unsigned int lineno, bool add_offset); 33 | bool view_column_draw(struct view *view, struct line *line, unsigned int lineno); 34 | 35 | void redraw_view(struct view *view); 36 | void redraw_view_from(struct view *view, int lineno); 37 | void redraw_view_dirty(struct view *view); 38 | bool draw_view_line(struct view *view, unsigned int lineno); 39 | 40 | #endif 41 | /* vim: set ts=8 sw=8 noexpandtab: */ 42 | -------------------------------------------------------------------------------- /include/tig/graph.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_GRAPH_H 15 | #define TIG_GRAPH_H 16 | 17 | #include "tig/types.h" 18 | 19 | #define GRAPH_COMMIT_COLOR (-1) 20 | #define GRAPH_COLORS 14 21 | 22 | struct graph; 23 | struct graph_symbol; 24 | 25 | struct graph_canvas { 26 | size_t size; /* The width of the graph array. */ 27 | struct graph_symbol *symbols; /* Symbols for this row. */ 28 | }; 29 | 30 | typedef bool (*graph_symbol_iterator_fn)(void *, const struct graph *graph, const struct graph_symbol *, int color_id, bool); 31 | 32 | struct graph { 33 | void *private; 34 | 35 | void (*done)(struct graph *graph); 36 | void (*done_rendering)(struct graph *graph); 37 | 38 | bool (*add_commit)(struct graph *graph, struct graph_canvas *canvas, 39 | const char *id, const char *parents, bool is_boundary); 40 | bool (*add_parent)(struct graph *graph, const char *parent); 41 | bool (*render_parents)(struct graph *graph, struct graph_canvas *canvas); 42 | bool (*is_merge)(struct graph_canvas *canvas); 43 | 44 | void (*foreach_symbol)(const struct graph *graph, const struct graph_canvas *canvas, graph_symbol_iterator_fn fn, void *data); 45 | 46 | const char *(*symbol_to_ascii)(const struct graph_symbol *symbol); 47 | const char *(*symbol_to_utf8)(const struct graph_symbol *symbol); 48 | const chtype *(*symbol_to_chtype)(const struct graph_symbol *symbol); 49 | }; 50 | 51 | struct graph *init_graph(enum graph_display display); 52 | 53 | #endif 54 | 55 | /* vim: set ts=8 sw=8 noexpandtab: */ 56 | -------------------------------------------------------------------------------- /include/tig/grep.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_GREP_H 15 | #define TIG_GREP_H 16 | 17 | #include "tig/view.h" 18 | 19 | void open_grep_view(struct view *prev); 20 | extern struct view grep_view; 21 | 22 | #endif 23 | /* vim: set ts=8 sw=8 noexpandtab: */ 24 | -------------------------------------------------------------------------------- /include/tig/help.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_HELP_H 15 | #define TIG_HELP_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view help_view; 20 | 21 | static inline void 22 | open_help_view(struct view *prev, enum open_flags flags) 23 | { 24 | open_view(prev, &help_view, flags); 25 | } 26 | 27 | #endif 28 | /* vim: set ts=8 sw=8 noexpandtab: */ 29 | -------------------------------------------------------------------------------- /include/tig/log.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_LOG_H 15 | #define TIG_LOG_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view log_view; 20 | 21 | static inline void 22 | open_log_view(struct view *prev, enum open_flags flags) 23 | { 24 | open_view(prev, &log_view, flags); 25 | } 26 | 27 | #endif 28 | /* vim: set ts=8 sw=8 noexpandtab: */ 29 | -------------------------------------------------------------------------------- /include/tig/main.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_MAIN_H 15 | #define TIG_MAIN_H 16 | 17 | #include "tig/view.h" 18 | #include "tig/graph.h" 19 | #include "tig/util.h" 20 | 21 | struct commit { 22 | char id[SIZEOF_REV]; /* SHA1 ID. */ 23 | const struct ident *author; /* Author of the commit. */ 24 | struct time time; /* Date from the author ident. */ 25 | struct graph_canvas graph; /* Ancestry chain graphics. */ 26 | char title[1]; /* First line of the commit message. */ 27 | }; 28 | 29 | struct main_state { 30 | struct graph *graph; 31 | struct commit current; 32 | char **reflog; 33 | size_t reflogs; 34 | int reflog_width; 35 | char reflogmsg[SIZEOF_STR / 2]; 36 | enum line_type goto_line_type; 37 | bool in_header; 38 | bool with_graph; 39 | bool first_parent; 40 | bool add_changes_staged; 41 | bool add_changes_unstaged; 42 | bool add_changes_untracked; 43 | }; 44 | 45 | bool main_get_column_data(struct view *view, const struct line *line, struct view_column_data *column_data); 46 | bool main_read(struct view *view, struct buffer *buf, bool force_stop); 47 | enum request main_request(struct view *view, enum request request, struct line *line); 48 | void main_select(struct view *view, struct line *line); 49 | void main_done(struct view *view); 50 | bool main_status_exists(struct view *view, enum line_type type); 51 | 52 | extern struct view main_view; 53 | 54 | static inline void 55 | open_main_view(struct view *prev, enum open_flags flags) 56 | { 57 | open_view(prev, &main_view, flags); 58 | } 59 | 60 | #endif 61 | /* vim: set ts=8 sw=8 noexpandtab: */ 62 | -------------------------------------------------------------------------------- /include/tig/map.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_MAP_H 15 | #define TIG_MAP_H 16 | 17 | #include "tig/tig.h" 18 | 19 | /* 20 | * String map. 21 | */ 22 | 23 | typedef unsigned int string_map_key_t; 24 | typedef string_map_key_t (*string_map_hash_fn)(const void *value); 25 | typedef const char *(*string_map_key_fn)(const void *value); 26 | typedef bool (*string_map_iterator_fn)(void *data, void *value); 27 | 28 | struct string_map { 29 | string_map_hash_fn hash_fn; 30 | string_map_key_fn key_fn; 31 | size_t init_size; 32 | void *htab; 33 | const char *key; 34 | }; 35 | 36 | extern string_map_hash_fn string_map_hash_helper; 37 | void *string_map_get(struct string_map *map, const char *key); 38 | void **string_map_get_at(struct string_map *map, const char *key); 39 | void *string_map_put(struct string_map *map, const char *key, void *value); 40 | void **string_map_put_to(struct string_map *map, const char *key); 41 | void *string_map_remove(struct string_map *map, const char *key); 42 | void string_map_clear(struct string_map *map); 43 | void string_map_foreach(struct string_map *map, string_map_iterator_fn iterator, void *data); 44 | 45 | #define DEFINE_STRING_MAP(name, type, key_member, init_size) \ 46 | static const char * \ 47 | name ## _key(const void *value) \ 48 | { \ 49 | return ((type) value)->key_member; \ 50 | } \ 51 | static string_map_key_t \ 52 | name ## _hash(const void *value) \ 53 | { \ 54 | return string_map_hash_helper(name ## _key(value)); \ 55 | } \ 56 | static struct string_map name = { \ 57 | name ## _hash, \ 58 | name ## _key, \ 59 | init_size, \ 60 | }; 61 | 62 | #endif 63 | /* vim: set ts=8 sw=8 noexpandtab: */ 64 | -------------------------------------------------------------------------------- /include/tig/pager.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_PAGER_H 15 | #define TIG_PAGER_H 16 | 17 | #include "tig/view.h" 18 | 19 | bool pager_get_column_data(struct view *view, const struct line *line, struct view_column_data *column_data); 20 | bool pager_common_read(struct view *view, const char *data, enum line_type type, struct line **line); 21 | enum request pager_request(struct view *view, enum request request, struct line *line); 22 | void pager_select(struct view *view, struct line *line); 23 | 24 | extern struct view pager_view; 25 | 26 | static inline void 27 | open_pager_view(struct view *prev, enum open_flags flags) 28 | { 29 | open_view(prev, &pager_view, flags); 30 | } 31 | 32 | #endif 33 | /* vim: set ts=8 sw=8 noexpandtab: */ 34 | -------------------------------------------------------------------------------- /include/tig/parse.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_PARSE_H 15 | #define TIG_PARSE_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/util.h" 19 | 20 | struct chunk_header_position { 21 | unsigned long position; 22 | unsigned long lines; 23 | }; 24 | 25 | struct chunk_header { 26 | struct chunk_header_position old; 27 | struct chunk_header_position new; 28 | }; 29 | 30 | bool parse_chunk_header(struct chunk_header *header, const char *line); 31 | bool parse_chunk_lineno(unsigned long *lineno, const char *chunk, int marker); 32 | 33 | struct blame_commit { 34 | char id[SIZEOF_REV]; /* SHA1 ID. */ 35 | char title[128]; /* First line of the commit message. */ 36 | const struct ident *author; /* Author of the commit. */ 37 | struct time time; /* Date from the author ident. */ 38 | const char *filename; /* Name of file. */ 39 | char parent_id[SIZEOF_REV]; /* Parent/previous SHA1 ID. */ 40 | const char *parent_filename; /* Parent/previous name of file. */ 41 | }; 42 | 43 | struct blame_header { 44 | char id[SIZEOF_REV]; /* SHA1 ID. */ 45 | size_t orig_lineno; 46 | size_t lineno; 47 | size_t group; 48 | }; 49 | 50 | bool parse_blame_header(struct blame_header *header, const char *text); 51 | bool parse_blame_info(struct blame_commit *commit, char author[SIZEOF_STR], char *line, bool use_author_date); 52 | 53 | /* Parse author lines where the name may be empty: 54 | * author 1138474660 +0100 55 | */ 56 | void parse_author_line(char *ident, const struct ident **author, struct time *time); 57 | 58 | size_t parse_size(const char *text); 59 | 60 | /* 61 | * Caches. 62 | */ 63 | const char *get_path(const char *path); 64 | struct ident *get_author(const char *name, const char *email); 65 | 66 | static inline unsigned int 67 | chunk_header_marker_length(const char *data) 68 | { 69 | unsigned int len = 0; 70 | for (; *data == '@'; data++) 71 | len++; 72 | return len; 73 | } 74 | 75 | #endif 76 | /* vim: set ts=8 sw=8 noexpandtab: */ 77 | -------------------------------------------------------------------------------- /include/tig/prompt.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_PROMPT_H 15 | #define TIG_PROMPT_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/keys.h" 19 | 20 | struct view; 21 | struct input; 22 | 23 | enum input_status { 24 | INPUT_OK, 25 | INPUT_SKIP, 26 | INPUT_DELETE, 27 | INPUT_STOP, 28 | INPUT_CANCEL 29 | }; 30 | 31 | struct menu_item { 32 | int hotkey; 33 | const char *text; 34 | void *data; 35 | }; 36 | 37 | typedef enum input_status (*input_handler)(struct input *input, struct key *key); 38 | 39 | struct input { 40 | input_handler handler; 41 | bool allow_empty; 42 | void *data; 43 | char buf[SIZEOF_STR]; 44 | char context[SIZEOF_STR]; 45 | }; 46 | 47 | enum input_status prompt_default_handler(struct input *input, struct key *key); 48 | char *read_prompt_incremental(const char *prompt, bool edit_mode, bool allow_empty, input_handler handler, void *data); 49 | char *read_prompt(const char *prompt); 50 | void prompt_init(void); 51 | bool prompt_yesno(const char *prompt); 52 | bool prompt_menu(const char *prompt, const struct menu_item *items, int *selected); 53 | 54 | enum request run_prompt_command(struct view *view, const char *argv[]); 55 | enum request open_prompt(struct view *view); 56 | enum request exec_run_request(struct view *view, struct run_request *req); 57 | 58 | #endif 59 | /* vim: set ts=8 sw=8 noexpandtab: */ 60 | -------------------------------------------------------------------------------- /include/tig/refdb.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_REFDB_H 15 | #define TIG_REFDB_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/types.h" 19 | #include "tig/util.h" 20 | 21 | struct argv_env; 22 | 23 | struct ref { 24 | struct ref *next; 25 | enum reference_type type; 26 | char id[SIZEOF_REV]; /* Commit SHA1 ID */ 27 | unsigned int valid:1; /* Is the ref still valid? */ 28 | char name[1]; /* Ref name; tag or head names are shortened. */ 29 | }; 30 | 31 | #define is_initial_commit() (!get_ref_head()) 32 | #define is_head_commit(rev) (!strcmp((rev), "HEAD") || (get_ref_head() && !strncmp(rev, get_ref_head()->id, SIZEOF_REV - 1))) 33 | #define ref_is_tag(ref) ((ref)->type == REFERENCE_TAG || (ref)->type == REFERENCE_LOCAL_TAG) 34 | #define ref_is_remote(ref) ((ref)->type == REFERENCE_REMOTE || (ref)->type == REFERENCE_TRACKED_REMOTE) 35 | 36 | #define foreach_ref_list(ref, id) for (ref = get_ref_list(id); ref; ref = ref->next) 37 | 38 | const struct ref *get_ref_head(); 39 | const struct ref *get_ref_list(const char *id); 40 | const struct ref *get_canonical_ref(const char *id); 41 | bool ref_list_contains_tag(const char *id); 42 | enum status_code load_refs(bool force); 43 | enum status_code add_ref(const char *id, char *name, const char *remote_name, const char *head); 44 | int ref_compare(const struct ref *ref1, const struct ref *ref2); 45 | void ref_update_env(struct argv_env *env, const struct ref *ref, bool recurse); 46 | 47 | bool refs_contain_tag(void); 48 | 49 | typedef bool (*ref_visitor_fn)(void *data, const struct ref *ref); 50 | void foreach_ref(ref_visitor_fn visitor, void *data); 51 | 52 | struct ref_format { 53 | const char *start; 54 | const char *end; 55 | }; 56 | 57 | const struct ref_format *get_ref_format(struct ref_format **formats, const struct ref *ref); 58 | enum status_code parse_ref_formats(struct ref_format ***formats, const char *argv[]); 59 | enum status_code format_ref_formats(struct ref_format **formats, char buf[], size_t bufsize); 60 | 61 | #endif 62 | 63 | /* vim: set ts=8 sw=8 noexpandtab: */ 64 | -------------------------------------------------------------------------------- /include/tig/reflog.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_REFLOG_H 15 | #define TIG_REFLOG_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view reflog_view; 20 | 21 | static inline void 22 | open_reflog_view(struct view *prev, enum open_flags flags) 23 | { 24 | open_view(prev, &reflog_view, flags); 25 | } 26 | 27 | #endif 28 | /* vim: set ts=8 sw=8 noexpandtab: */ 29 | -------------------------------------------------------------------------------- /include/tig/refs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_REFS_H 15 | #define TIG_REFS_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view refs_view; 20 | 21 | static inline void 22 | open_refs_view(struct view *prev, enum open_flags flags) 23 | { 24 | open_view(prev, &refs_view, flags); 25 | } 26 | 27 | #endif 28 | /* vim: set ts=8 sw=8 noexpandtab: */ 29 | -------------------------------------------------------------------------------- /include/tig/repo.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_REPO_H 15 | #define TIG_REPO_H 16 | 17 | #include "tig/tig.h" 18 | 19 | typedef char repo_ref[SIZEOF_REF]; 20 | typedef char repo_rev[SIZEOF_REV]; 21 | typedef char repo_str[SIZEOF_STR]; 22 | 23 | #define REPO_INFO(_) \ 24 | _(repo_ref, head) \ 25 | _(repo_rev, head_id) \ 26 | _(repo_ref, remote) \ 27 | _(repo_ref, upstream) \ 28 | _(repo_str, cdup) \ 29 | _(repo_str, prefix) \ 30 | _(repo_str, git_dir) \ 31 | _(repo_str, worktree) \ 32 | _(repo_str, exec_dir) \ 33 | _(bool, is_inside_work_tree) 34 | 35 | #define REPO_INFO_FIELDS(type, name) type name; 36 | 37 | struct repo_info { 38 | REPO_INFO(REPO_INFO_FIELDS) 39 | }; 40 | 41 | extern struct repo_info repo; 42 | 43 | enum status_code load_repo_info(void); 44 | enum status_code load_repo_head(void); 45 | 46 | struct index_diff { 47 | int staged; 48 | int unstaged; 49 | int untracked; 50 | }; 51 | 52 | bool index_diff(struct index_diff *diff, bool untracked, bool count_all); 53 | bool update_index(void); 54 | 55 | #endif 56 | /* vim: set ts=8 sw=8 noexpandtab: */ 57 | -------------------------------------------------------------------------------- /include/tig/search.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_SEARCH_H 15 | #define TIG_SEARCH_H 16 | 17 | #include "tig/view.h" 18 | 19 | void reset_search(struct view *view); 20 | void search_view(struct view *view, enum request request); 21 | void find_next(struct view *view, enum request request); 22 | void find_merge(struct view *view, enum request request); 23 | bool grep_text(struct view *view, const char *text[]); 24 | 25 | #endif 26 | /* vim: set ts=8 sw=8 noexpandtab: */ 27 | -------------------------------------------------------------------------------- /include/tig/stage.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_STAGE_H 15 | #define TIG_STAGE_H 16 | 17 | #include "tig/view.h" 18 | 19 | struct status; 20 | 21 | extern struct view stage_view; 22 | 23 | void open_stage_view(struct view *prev, struct status *status, enum line_type type, enum open_flags flags); 24 | 25 | #endif 26 | /* vim: set ts=8 sw=8 noexpandtab: */ 27 | -------------------------------------------------------------------------------- /include/tig/stash.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_STASH_H 15 | #define TIG_STASH_H 16 | 17 | #include "tig/view.h" 18 | 19 | extern struct view stash_view; 20 | 21 | static inline void 22 | open_stash_view(struct view *prev, enum open_flags flags) 23 | { 24 | open_view(prev, &stash_view, flags); 25 | } 26 | 27 | #endif 28 | /* vim: set ts=8 sw=8 noexpandtab: */ 29 | -------------------------------------------------------------------------------- /include/tig/status.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_STATUS_H 15 | #define TIG_STATUS_H 16 | 17 | #include "tig/view.h" 18 | #include "tig/line.h" 19 | 20 | struct status { 21 | char status; 22 | struct { 23 | mode_t mode; 24 | char rev[SIZEOF_REV]; 25 | char name[SIZEOF_STR]; 26 | } old; 27 | struct { 28 | mode_t mode; 29 | char rev[SIZEOF_REV]; 30 | char name[SIZEOF_STR]; 31 | } new; 32 | }; 33 | 34 | bool status_update_file(struct status *status, enum line_type type); 35 | bool status_update_files(struct view *view, struct line *line); 36 | bool status_get_diff(struct status *file, const char *buf, size_t bufsize); 37 | 38 | bool status_revert(struct status *status, enum line_type type, bool has_none); 39 | bool status_exists(struct view *view, struct status *status, enum line_type type); 40 | 41 | bool status_stage_info_(char *buf, size_t bufsize, 42 | enum line_type type, struct status *status); 43 | #define status_stage_info(buf, type, status) \ 44 | status_stage_info_(buf, sizeof(buf), type, status) 45 | extern struct view status_view; 46 | 47 | void open_status_view(struct view *prev, bool untracked_only, enum open_flags flags); 48 | 49 | #endif 50 | /* vim: set ts=8 sw=8 noexpandtab: */ 51 | -------------------------------------------------------------------------------- /include/tig/tree.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_TREE_H 15 | #define TIG_TREE_H 16 | 17 | #include "tig/view.h" 18 | 19 | void open_blob_editor(const char *id, const char *name, unsigned int lineno); 20 | 21 | extern struct view tree_view; 22 | 23 | static inline void 24 | open_tree_view(struct view *prev, enum open_flags flags) 25 | { 26 | open_view(prev, &tree_view, flags); 27 | } 28 | 29 | #endif 30 | /* vim: set ts=8 sw=8 noexpandtab: */ 31 | -------------------------------------------------------------------------------- /include/tig/ui.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_UI_H 15 | #define TIG_UI_H 16 | 17 | const char *open_file_finder(const char *commit); 18 | 19 | #endif 20 | /* vim: set ts=8 sw=8 noexpandtab: */ 21 | -------------------------------------------------------------------------------- /include/tig/watch.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #ifndef TIG_WATCH_H 15 | #define TIG_WATCH_H 16 | 17 | #include "tig/tig.h" 18 | #include "tig/types.h" 19 | 20 | enum watch_event { 21 | WATCH_EVENT_SWITCH_VIEW, 22 | WATCH_EVENT_AFTER_COMMAND, 23 | WATCH_EVENT_LOAD, 24 | WATCH_EVENT_PERIODIC, 25 | }; 26 | 27 | enum watch_trigger { 28 | WATCH_NONE = 0, 29 | WATCH_INDEX_STAGED_YES = 1 << 0, 30 | WATCH_INDEX_STAGED_NO = 1 << 1, 31 | WATCH_INDEX_UNSTAGED_YES = 1 << 2, 32 | WATCH_INDEX_UNSTAGED_NO = 1 << 3, 33 | WATCH_INDEX_UNTRACKED_YES = 1 << 4, 34 | WATCH_INDEX_UNTRACKED_NO = 1 << 5, 35 | WATCH_HEAD = 1 << 6, 36 | WATCH_STASH = 1 << 7, 37 | WATCH_REFS = 1 << 8, 38 | 39 | WATCH_INDEX_STAGED = WATCH_INDEX_STAGED_YES | WATCH_INDEX_STAGED_NO, 40 | WATCH_INDEX_UNSTAGED = WATCH_INDEX_UNSTAGED_YES | WATCH_INDEX_UNSTAGED_NO, 41 | WATCH_INDEX_UNTRACKED = WATCH_INDEX_UNTRACKED_YES | WATCH_INDEX_UNTRACKED_NO, 42 | WATCH_INDEX = WATCH_INDEX_STAGED | WATCH_INDEX_UNSTAGED | WATCH_INDEX_UNTRACKED, 43 | }; 44 | 45 | struct watch { 46 | struct watch *next; 47 | enum watch_trigger triggers; 48 | enum watch_trigger changed; 49 | enum watch_trigger state; 50 | }; 51 | 52 | void watch_register(struct watch *watch, enum watch_trigger triggers); 53 | void watch_unregister(struct watch *watch); 54 | bool watch_dirty(struct watch *watch); 55 | enum watch_trigger watch_update(enum watch_event event); 56 | enum watch_trigger watch_update_single(struct watch *watch, enum watch_event event); 57 | void watch_apply(struct watch *source, enum watch_trigger changed); 58 | int watch_periodic(int interval); 59 | 60 | #endif 61 | /* vim: set ts=8 sw=8 noexpandtab: */ 62 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: tig 2 | version: git 3 | summary: Text-mode interface for git 4 | license: GPL-2.0-or-later 5 | description: | 6 | Tig is an ncurses-based text-mode interface for Git. It functions mainly as a 7 | Git repository browser, but can also assist in staging changes for commit at 8 | chunk level and act as a pager for output from various Git commands. 9 | 10 | grade: devel # must be 'stable' to release into candidate/stable channels 11 | confinement: strict 12 | 13 | base: core18 14 | 15 | plugs: 16 | config-tig: 17 | interface: personal-files 18 | read: 19 | - $HOME/.tigrc 20 | 21 | apps: 22 | tig: 23 | command: bin/tig 24 | plugs: 25 | - config-tig 26 | 27 | parts: 28 | tig: 29 | source: . 30 | plugin: autotools 31 | build-packages: 32 | - pkg-config 33 | - libncursesw5-dev 34 | - libreadline-dev 35 | -------------------------------------------------------------------------------- /src/graph.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #include "tig/tig.h" 15 | #include "tig/graph.h" 16 | 17 | struct graph *init_graph_v1(void); 18 | struct graph *init_graph_v2(void); 19 | 20 | struct graph * 21 | init_graph(enum graph_display display) 22 | { 23 | if (display == GRAPH_DISPLAY_V1) 24 | return init_graph_v1(); 25 | if (display == GRAPH_DISPLAY_V2) 26 | return init_graph_v2(); 27 | return NULL; 28 | } 29 | 30 | /* vim: set ts=8 sw=8 noexpandtab: */ 31 | -------------------------------------------------------------------------------- /src/reflog.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #include "tig/display.h" 15 | #include "tig/draw.h" 16 | #include "tig/git.h" 17 | #include "tig/main.h" 18 | 19 | static enum status_code 20 | reflog_open(struct view *view, enum open_flags flags) 21 | { 22 | struct main_state *state = view->private; 23 | const char *reflog_argv[] = { 24 | "git", "reflog", "show", encoding_arg, "%(cmdlineargs)", 25 | "%(revargs)", "--no-color", "--pretty=raw", NULL 26 | }; 27 | 28 | if (is_initial_view(view) && opt_file_args) 29 | die("No revisions match the given arguments."); 30 | 31 | state->with_graph = false; 32 | watch_register(&view->watch, WATCH_HEAD | WATCH_REFS); 33 | return begin_update(view, NULL, reflog_argv, flags); 34 | } 35 | 36 | static enum request 37 | reflog_request(struct view *view, enum request request, struct line *line) 38 | { 39 | struct commit *commit = line->data; 40 | 41 | switch (request) { 42 | case REQ_ENTER: 43 | { 44 | const char *main_argv[] = { 45 | GIT_MAIN_LOG(encoding_arg, commit_order_arg(), 46 | "%(mainargs)", "", commit->id, "", 47 | show_notes_arg(), log_custom_pretty_arg(false)) 48 | }; 49 | enum open_flags flags = view_is_displayed(view) ? OPEN_SPLIT : OPEN_DEFAULT; 50 | 51 | if (!argv_format(main_view.env, &main_view.argv, main_argv, 0)) 52 | report("Failed to format argument"); 53 | else 54 | open_main_view(view, flags | OPEN_PREPARED); 55 | return REQ_NONE; 56 | } 57 | 58 | default: 59 | return main_request(view, request, line); 60 | } 61 | } 62 | 63 | static struct view_ops reflog_ops = { 64 | "reference", 65 | argv_env.head, 66 | VIEW_LOG_LIKE | VIEW_REFRESH, 67 | sizeof(struct main_state), 68 | reflog_open, 69 | main_read, 70 | view_column_draw, 71 | reflog_request, 72 | view_column_grep, 73 | main_select, 74 | main_done, 75 | view_column_bit(AUTHOR) | view_column_bit(COMMIT_TITLE) | 76 | view_column_bit(DATE) | view_column_bit(ID) | 77 | view_column_bit(LINE_NUMBER), 78 | main_get_column_data, 79 | }; 80 | 81 | DEFINE_VIEW(reflog); 82 | 83 | /* vim: set ts=8 sw=8 noexpandtab: */ 84 | -------------------------------------------------------------------------------- /src/request.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #include "tig/tig.h" 15 | #include "tig/types.h" 16 | #include "tig/request.h" 17 | 18 | static const struct request_info req_info[] = { 19 | #define REQ_GROUP(help) { 0, NULL, 0, (help) }, 20 | #define REQ_(req, help) { REQ_##req, (#req), STRING_SIZE(#req), (help) } 21 | REQ_INFO 22 | #undef REQ_GROUP 23 | #undef REQ_ 24 | }; 25 | 26 | enum request 27 | get_request(const char *name) 28 | { 29 | int namelen = strlen(name); 30 | int i; 31 | 32 | for (i = 0; i < ARRAY_SIZE(req_info); i++) 33 | if (enum_equals(req_info[i], name, namelen)) 34 | return req_info[i].request; 35 | 36 | return REQ_UNKNOWN; 37 | } 38 | 39 | const char * 40 | get_request_name(enum request request) 41 | { 42 | int i; 43 | 44 | for (i = 0; i < ARRAY_SIZE(req_info); i++) 45 | if (req_info[i].request == request) 46 | return enum_name(req_info[i].name); 47 | return request == REQ_UNKNOWN ? "unknown" : "run request"; 48 | } 49 | 50 | bool 51 | foreach_request(bool (*visitor)(void *data, const struct request_info *req_info, const char *group), void *data) 52 | { 53 | const char *group = NULL; 54 | int i; 55 | 56 | for (i = 0; i < ARRAY_SIZE(req_info); i++) { 57 | if (!req_info[i].request) { 58 | group = req_info[i].help; 59 | continue; 60 | } 61 | 62 | if (!visitor(data, &req_info[i], group)) 63 | return false; 64 | } 65 | 66 | return true; 67 | } 68 | 69 | /* vim: set ts=8 sw=8 noexpandtab: */ 70 | -------------------------------------------------------------------------------- /test/API.adoc: -------------------------------------------------------------------------------- 1 | Testing API 2 | ----------- 3 | 4 | file(filename, [content, ...]) [< content]:: 5 | 6 | tig_script(name, content, [content, ...]):: 7 | 8 | steps(content, [content, ...]):: 9 | 10 | stdin([content, ...]) [< content]:: 11 | 12 | tigrc([content, ...]) [< content]:: 13 | 14 | gitconfig(content, ...):: 15 | 16 | in_work_dir(command, [args, ...]):: 17 | 18 | assert_equals(filename, [whitespace, note, ...]) < expected:: 19 | 20 | assert_not_exists(filename):: 21 | 22 | assert_vars(count):: 23 | 24 | test_todo([note, ...]):: 25 | 26 | test_timeout(seconds):: 27 | 28 | require_git_version(version, [note, ...]):: 29 | 30 | test_require(git-worktree, address-sanitizer, diff-highlight, readline):: 31 | 32 | test_setup():: 33 | 34 | test_tig():: 35 | 36 | Set up a controlled environment and report the test result. 37 | Input to be processed via stdin is passed and stderr is captured and 38 | can be used for later assertions. 39 | Example 40 | -------------------------------------------------------------------------------- 41 | test_tig show 1a2b3c4d5e6f 42 | -------------------------------------------------------------------------------- 43 | 44 | test_graph() < expected:: 45 | 46 | test_case([--before=, --after=, --script=, --args=, --cwd=, --tigrc=, --assert-stderr=, --todo=, --subshell=, --timeout=]) < expected:: 47 | 48 | run_test_cases():: 49 | 50 | -------------------------------------------------------------------------------- /test/blame/initial-diff-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | steps ' 7 | :save-display initial-diff.screen 8 | :20 # Move to a deleted line. 9 | :view-blame 10 | :scroll-right 11 | :save-display blame-deleted-line.screen 12 | ' 13 | 14 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 15 | 16 | LINES=23 test_tig show a1dcf1a 17 | 18 | assert_equals 'initial-diff.screen' < 21 | AuthorDate: Sat Mar 1 15:59:02 2014 -0500 22 | Commit: Jonas Fonseca 23 | CommitDate: Sat Mar 1 15:59:02 2014 -0500 24 | 25 | Add type parameter for js.Dynamic 26 | --- 27 | common/src/main/scala/org/scalajs/benchmark/Benchmark.scala | 2 +- 28 | 1 file changed, 1 insertion(+), 1 deletion(-) 29 | 30 | diff --git a/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala b/commo 31 | index 65f914a..3aa4320 100644 32 | --- a/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala 33 | +++ b/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala 34 | @@ -15,7 +15,7 @@ object Benchmark { 35 | val benchmarks = js.Array[Benchmark]() 36 | val benchmarkApps = js.Array[BenchmarkApp]() 37 | 38 | - val global = js.Dynamic.global.asInstanceOf[js.Dictionary] 39 | + val global = js.Dynamic.global.asInstanceOf[js.Dictionary[js.Any]] 40 | [diff] a1dcf1aaa11470978db1d5d8bcf9e16201eb70ff - line 1 of 24 87% 41 | EOF 42 | 43 | # Make sure that we find the commit that introduce the deleted line. 44 | assert_equals 'blame-deleted-line.screen' < file 28 | git add file 29 | export GIT_AUTHOR_DATE="1486403695" 30 | export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" 31 | git commit -m "Initial commit" 32 | echo "changed line" > file 33 | git stash 34 | } 35 | 36 | LINES=3 test_tig 37 | 38 | assert_equals 'diff.screen' <README.md 25 | git add README.md 26 | git_commit -m "tomorrow" 27 | } 28 | 29 | test_tig 30 | 31 | assert_equals 'wrapped.screen' < 33 | AuthorDate: Sat Mar 1 15:59:02 2014 -0500 34 | Commit: Jonas Fonseca 35 | CommitDate: Sat Mar 1 15:59:02 2014 -0500 36 | 37 | Add type parameter for js.Dynamic 38 | --- 39 | common/src/main/scala/org/scalajs/benchmark/Benchmark.scala | 2 +- 40 | 1 file changed, 1 insertion(+), 1 deletion(-) 41 | 42 | diff --git a/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala b/commo 43 | index 65f914a..3aa4320 100644 44 | --- a/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala 45 | +++ b/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala 46 | @@ -15,7 +15,7 @@ object Benchmark { 47 | val benchmarks = js.Array[Benchmark]() 48 | val benchmarkApps = js.Array[BenchmarkApp]() 49 | 50 | - val global = js.Dynamic.global.asInstanceOf[js.Dictionary] 51 | + val global = js.Dynamic.global.asInstanceOf[js.Dictionary[js.Any]] 52 | global("runScalaJSBenchmarks") = runBenchmarks _ 53 | global("initScalaJSBenchmarkApps") = initBenchmarkApps _ 54 | 55 | 56 | 57 | 58 | 59 | [diff] a1dcf1aaa11470978db1d5d8bcf9e16201eb70ff - line 1 of 24 100% 60 | EOF 61 | -------------------------------------------------------------------------------- /test/diff/diff-highlight-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 7 | 8 | file bin/diff-highlight < 22 | AuthorDate: Sat Mar 1 15:59:02 2014 -0500 23 | Commit: Jonas Fonseca 24 | CommitDate: Sat Mar 1 15:59:02 2014 -0500 25 | 26 | Changed by diff-highlight 27 | --- 28 | common/src/main/scala/org/scalajs/benchmark/Benchmark.scala | 2 +- 29 | 1 file changed, 1 insertion(+), 1 deletion(-) 30 | 31 | diff --git a/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala b/commo 32 | index 65f914a..3aa4320 100644 33 | --- a/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala 34 | +++ b/common/src/main/scala/org/scalajs/benchmark/Benchmark.scala 35 | @@ -15,7 +15,7 @@ object Benchmark { 36 | val benchmarks = js.Array[Benchmark]() 37 | val benchmarkApps = js.Array[BenchmarkApp]() 38 | 39 | - val global = js.Dynamic.global.asInstanceOf[js.Dictionary] 40 | + val global = js.Dynamic.global.asInstanceOf[js.Dictionary[js.Any]] 41 | global("runScalaJSBenchmarks") = runBenchmarks _ 42 | global("initScalaJSBenchmarkApps") = initBenchmarkApps _ 43 | 44 | 45 | 46 | 47 | 48 | [diff] a1dcf1aaa11470978db1d5d8bcf9e16201eb70ff - line 1 of 24 100% 49 | EOF 50 | 51 | test_case diff-highlight-custom \ 52 | --tigrc='set diff-highlight = wc' \ 53 | --args='show master^' \ 54 | < README.md 23 | git add README.md 24 | } 25 | 26 | test_tig 27 | 28 | assert_equals 'added-line-number.screen' < 30 | ' 31 | 32 | setup_submodule_project() 33 | { 34 | create_repo_from_tgz "$base_dir/files/repo-two.tgz" 35 | git submodule update 36 | mkdir -p repo-two-a/src/subdir 37 | } 38 | 39 | test_exec_work_dir setup_submodule_project 40 | work_dir="$work_dir/repo-two-a/src/subdir" 41 | 42 | test_tig show 8cc26dd6e80e2fa7fa98d12f4670d8983bc83678 43 | 44 | assert_equals 'diff.screen' < 47 | | AuthorDate: Thu Jun 4 16:19:40 2009 +0000 48 | | Commit: Committer 49 | 5| CommitDate: Thu Jun 4 16:19:40 2009 +0000 50 | | 51 | | [repo-two-a] Commit 3 52 | | --- 53 | | include/api.h | 1 + 54 | 10| 1 file changed, 1 insertion(+) 55 | | 56 | | diff --git a/include/api.h b/include/api.h 57 | | index f2eb956..1da0f3f 100644 58 | | --- a/include/api.h 59 | 15| +++ b/include/api.h 60 | | @@ -1 +1,2 @@ 61 | | include/api.h 62 | | +include/api.h 63 | 64 | 65 | [diff] Press '' to jump to file diff - line 9 of 18 100% 66 | EOF 67 | 68 | # The file is called include/api.h and contains its name on two lines 69 | assert_equals 'editor.log' < 27 | AuthorDate: Sat Mar 1 17:26:01 2014 -050 28 | +0 29 | Commit: Jonas Fonseca 31 | CommitDate: Sat Mar 1 17:26:01 2014 -050 32 | +0 33 | 34 | WIP: Upgrade to 0.4-SNAPSHOT and DCE 35 | --- 36 | .../benchmark-runner.sh | 5 ++- 37 | .../Benchmark.scala | 11 +++--- 38 | .../BenchmarkApp.scala | 2 +- 39 | common/start-benchmark.js | 9 ++++- 40 | deltablue/exports.js | 13 ------- 41 | .../DeltaBlue.scala | 7 ++++ 42 | project/Build.scala | 13 ++----- 43 | project/build.sbt | 5 ++- 44 | richards/exports.js | 13 ------- 45 | .../Richards.scala | 3 ++ 46 | run.sh | 2 +- 47 | sudoku/exports.js | 13 ------- 48 | .../sudoku/Sudoku.scala | 2 + 49 | tracer/exports.js | 13 ------- 50 | [diff] ee912870202200a0b9cf4fd86ba572 5% 51 | EOF 52 | -------------------------------------------------------------------------------- /test/files/refs-repo.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas/tig/b0f77a7ed62f823ef7464080e1376854902509b5/test/files/refs-repo.tgz -------------------------------------------------------------------------------- /test/files/repo-authornamechange.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas/tig/b0f77a7ed62f823ef7464080e1376854902509b5/test/files/repo-authornamechange.tgz -------------------------------------------------------------------------------- /test/files/repo-one.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas/tig/b0f77a7ed62f823ef7464080e1376854902509b5/test/files/repo-one.tgz -------------------------------------------------------------------------------- /test/files/repo-two.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas/tig/b0f77a7ed62f823ef7464080e1376854902509b5/test/files/repo-two.tgz -------------------------------------------------------------------------------- /test/files/scala-js-benchmarks.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas/tig/b0f77a7ed62f823ef7464080e1376854902509b5/test/files/scala-js-benchmarks.tgz -------------------------------------------------------------------------------- /test/graph/00-simple-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Graph test: simple 4 | 5 | . libtest.sh 6 | 7 | test_graph <stderr >stdout 14 | 15 | assert_equals stderr < make test/help/all-keybindings-test && cp test/tmp/help/all-keybindings-test/help-default.screen test/help/all-keybindings-test.expected" \ 26 | < "$expected" 27 | -------------------------------------------------------------------------------- /test/help/user-command-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | 5 | export COLUMNS=100 6 | 7 | tigrc < 19 | ?toggle author 20 | :save-display default.screen 21 | ' 22 | 23 | stdin < view-close Close the current view 52 | Searching 53 | , , find-next Find next search match 54 | , , find-prev Find previous search match 55 | [-] main bindings 56 | Cursor navigation 57 | G move-last-line Move cursor to last line 58 | [help] - line 81 of 148 72% 59 | EOF 60 | -------------------------------------------------------------------------------- /test/log/log-graph-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | steps ' 7 | :save-display log-graph.screen 8 | ' 9 | 10 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 11 | 12 | test_tig log --graph e59a941 13 | 14 | assert_equals 'log-graph.screen' < 18 | | | Date: Thu Jan 16 07:47:58 2014 -0800 19 | | | 20 | | | Merge pull request #4 from phaller/patch-1 21 | | | 22 | | | Fix link to Dart benchmark harness 23 | | | 24 | | | README.md | 2 +- 25 | | | 1 file changed, 1 insertion(+), 1 deletion(-) 26 | | | 27 | | * commit 940efafc379db7c6df99449d6c4da98c6a2b3d07 28 | |/ Author: Philipp Haller 29 | | Date: Thu Jan 16 15:32:52 2014 +0100 30 | | 31 | | Fix link to Dart benchmark harness 32 | | 33 | | README.md | 2 +- 34 | | 1 file changed, 1 insertion(+), 1 deletion(-) 35 | | 36 | * commit 110e090f815f40d649f5432172584057b550a160 37 | | Author: Jonas Fonseca 38 | | Date: Tue Dec 17 00:02:15 2013 +0100 39 | | 40 | | Update links to reflect project name change 41 | | 42 | | scalajs-benchmarks -> scala-js-benchmarks 43 | [log] e59a941c4e7d51cd172ee2767a031f5f3fd25d05 - line 1 of 559 5% 44 | EOF 45 | -------------------------------------------------------------------------------- /test/log/start-on-line-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 7 | 8 | steps ' 9 | :save-display position.screen 10 | ' 11 | 12 | test_tig log +42 13 | 14 | assert_equals 'position.screen' < 16 | Date: Sat Mar 1 15:59:02 2014 -0500 17 | 18 | Add type parameter for js.Dynamic 19 | 20 | common/src/main/scala/org/scalajs/benchmark/Benchmark.scala | 2 +- 21 | 1 file changed, 1 insertion(+), 1 deletion(-) 22 | 23 | commit 296fc90ba2c47ba3d2b6ab8e984ea3a82bb4cd6e 24 | Author: Jonas Fonseca 25 | Date: Thu Jan 16 22:51:27 2014 -0500 26 | 27 | Move classes under org.scalajs.benchmark package scope 28 | 29 | common/Benchmark.scala | 110 ---- 30 | common/BenchmarkApp.scala | 47 -- 31 | common/DOMTypes.scala | 49 -- 32 | .../scala/org/scalajs/benchmark/Benchmark.scala | 110 ++++ 33 | .../scala/org/scalajs/benchmark/BenchmarkApp.scala | 46 ++ 34 | .../scala/org/scalajs/benchmark/dom/DOMTypes.scala | 49 ++ 35 | deltablue/DeltaBlue.scala | 704 --------------------- 36 | deltablue/exports.js | 2 +- 37 | .../scalajs/benchmark/deltablue/DeltaBlue.scala | 704 +++++++++++++++++++++ 38 | richards/Richards.scala | 460 -------------- 39 | richards/exports.js | 2 +- 40 | .../org/scalajs/benchmark/richards/Richards.scala | 460 ++++++++++++++ 41 | sudoku/Sudoku.scala | 197 ------ 42 | sudoku/exports.js | 2 +- 43 | [log] 296fc90ba2c47ba3d2b6ab8e984ea3a82bb4cd6e - line 42 of 668 8% 44 | EOF 45 | -------------------------------------------------------------------------------- /test/main/author-name-change-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Test display and options specific to the main view. 4 | 5 | . libtest.sh 6 | . libgit.sh 7 | 8 | export LINES=5 9 | 10 | tigrc <> prepare.log 2>> prepare.log 16 | 17 | test_tig --boundary --all ^master 18 | 19 | assert_equals 'merge-view.screen' < Commit 10 B 44 | 2010-03-04 04:09 +0000 A. U. Thor * Commit 10 A 45 | 2010-02-23 15:46 +0000 Max Power * Commit 9 E 46 | 2010-02-15 03:24 +0000 Jørgen Thygesen Brahe * Commit 9 D 47 | 2010-02-06 15:02 +0000 作者 * Commit 9 C 48 | 2010-01-29 02:40 +0000 René Lévesque * Commit 9 B 49 | 2010-01-20 14:18 +0000 A. U. Thor * Commit 9 A 50 | 2010-01-12 01:56 +0000 Max Power * Commit 8 E 51 | 2010-01-03 13:33 +0000 Jørgen Thygesen Brahe * Commit 8 D 52 | 2009-12-26 01:11 +0000 作者 * [r1.1.2] [r1.1.x] Commit 8 53 | 2009-12-17 12:49 +0000 René Lévesque * [r1.0] Commit 8 B 54 | 2009-12-09 00:27 +0000 A. U. Thor * Commit 8 A 55 | [main] 042f71a7592228ae84cbb3642c2666dcd35aa527 - commit 1 of 51 31% 56 | EOF 57 | -------------------------------------------------------------------------------- /test/main/commit-order-edge-case-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=10 7 | 8 | tigrc < 7363156 e75e9f3a 1440007968 -0700Check GBM_BO_USE_LINEAR correctly v2 2 | commit > e75e9f3 37b389ea 1440007968 -0700extend conditional group GBM_BO_USE_LINEAR over both usages 3 | commit > 37b389e 2291704a 1440007968 -0700glamor: Deal with glamor_glyphs_init being removed from xserver 4 | commit > 2291704 e71be4aa 1440007968 -0700add some new tonga pci ids 5 | commit > e71be4a b795d1ea 1440007968 -0700add new bonaire pci id 6 | commit > b795d1e 7e3b273a 1440007968 -0700Link against libgbm 7 | commit > 7e3b273 4840f91a 1440007968 -0700Disable tiling for PRIME shared pixmap 8 | commit > 4840f91 b69c5b3a 1440007968 -0700Use gbm_bo_get_fd to get DMA_BUF fd 9 | commit > b69c5b3 91aa694a 1440007968 -0700ddx: use amdgpu_query_crtc_from_id 10 | commit > 91aa694 afc3304a 1440007968 -0700ddx: remove AMDGPUIsAccelWorking 11 | commit > afc3304 8a34a81a 1440007968 -0700ddx: enable acceleration by default on Hawaii 12 | commit > 8a34a81 9f61a55a 1440007968 -0700Remove throttling from amdgpu_dri2_copy_region2 13 | commit > 9f61a55 a49ad11a 1440007968 -0700fixup README 14 | commit > a49ad11 fa4aed6a 1440007968 -0700Add 10-amdgpu.conf xorg.conf.d snippet 15 | commit > fa4aed6 fe4a4b6a 1440007968 -0700Document Option "AccelMethod" in the manpage 16 | commit > fe4a4b6 84df3e7a 1440007968 -0700Fix build when gbm.h doesn't define GBM_BO_USE_LINEAR 17 | commit > 84df3e7 b947f4ba 1440007968 -0700glamor: Handle GLAMOR_* flags removed from xserver 18 | commit > b947f4b ff62bf6a 1440007968 -0700Move #include "radeon_glamor.h" from amdgpu_drv.h to where it's needed 19 | commit > ff62bf6 a 1440007968 -0700amdgpu: add the xf86-video-amdgpu driver -------------------------------------------------------------------------------- /test/main/git-alias-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=5 7 | 8 | benchmarks_git="$output_dir/benchmarks.git" 9 | benchmarks_dir="$output_dir/$work_dir" 10 | 11 | tigrc <> "$output_dir/alias-vars" 24 | EOF 25 | 26 | test_setup_work_dir() 27 | { 28 | mkdir -p "$output_dir/base" 29 | cd "$output_dir/base" 30 | create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 31 | git branch work-branch ee912870202200a0b9cf4fd86ba57243212d341e 32 | git worktree add "$output_dir/$work_dir" work-branch 33 | git config --global alias.tig !tig 34 | git config --global alias.alias-vars !alias-vars 35 | } 36 | 37 | test_exec_work_dir test_setup_work_dir 38 | 39 | runner=git 40 | 41 | work_dir="$work_dir/deltablue" 42 | test_tig -- src/main/scala 43 | in_work_dir git alias-vars 44 | 45 | assert_equals 'alias-vars' <"$work_dir/.mailmap" < A. U. Thor " 12 | Ti-Poil René Lévesque " 13 | 龙 作者 " 14 | Stargazer Jørgen Thygesen Brahe " 15 | Full Throttle Max Power " 16 | ¯\_(ツ)_/¯ Committer 17 | EOF 18 | 19 | tigrc < 55 | AuthorDate: Wed Apr 7 05:37:40 2010 +0000 56 | Commit: ¯\_(ツ)_/¯ 57 | CommitDate: Wed Apr 7 05:37:40 2010 +0000 58 | 59 | Commit 10 E 60 | 61 | 62 | 63 | 64 | 65 | [diff] 5cb3412a5e06e506840495b91acc885037a48b72 - line 1 of 8 100% 66 | EOF 67 | -------------------------------------------------------------------------------- /test/main/main-options-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Test display and options specific to the main view. 4 | 5 | . libtest.sh 6 | . libgit.sh 7 | 8 | export LINES=16 9 | 10 | tigrc < repo.log 2>&1 20 | 21 | test_tig --merge 22 | 23 | assert_equals 'main-with-conflict.screen' <file1 19 | git add file1 20 | git_commit -m "commit1" 21 | printf 'data\n' >file2 22 | git add file2 23 | git rm file1 24 | } 25 | 26 | test_tig 27 | 28 | assert_equals 'default.screen' < Commit 8 B 27 | 2009-12-09 00:27 +0000 A. U. Thor Commit 8 A 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | [main] d9a8c8b1e52ba7f1673cebb271f1fc0bdac3579b - commit 1 of 5 100% 38 | EOF 39 | -------------------------------------------------------------------------------- /test/main/unbind-default-quit-key-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | tigrc < 12 | :save-display result.screen 13 | ' 14 | 15 | tigrc < checkout: moving from r1.0 to r1.1.2 25 | 957f2b3 [r1.0] checkout: moving from master to r1.0 26 | 5cb3412 [master] {max-power/master} {origin/HEAD} {origin/master} reset: moving 27 | 5cb3412 [master] {max-power/master} {origin/HEAD} {origin/master} clone: from /o 28 | 29 | 30 | 31 | 32 | 33 | [reflog] HEAD@{0} - reference 1 of 4 100% 34 | 2009-12-26 01:11 +0000 作者 * [r1.1.2] [r1.1.x] Commit 8 35 | 2009-12-17 12:49 +0000 René Lévesque * [r1.0] Commit 8 B 36 | 2009-12-09 00:27 +0000 A. U. Thor * Commit 8 A 37 | 2009-11-30 12:05 +0000 Max Power * {max-power/mp/gh-123} Commit 7 E 38 | 2009-11-21 23:43 +0000 Jørgen Thygesen Brahe * Commit 7 D 39 | 2009-11-13 11:20 +0000 作者 * Commit 7 C 40 | 2009-11-04 22:58 +0000 René Lévesque * Commit 7 B 41 | 2009-10-27 10:36 +0000 A. U. Thor * Commit 7 A 42 | 2009-10-18 22:14 +0000 Max Power * Commit 6 E 43 | 2009-10-10 09:52 +0000 Jørgen Thygesen Brahe * Commit 6 D 44 | 2009-10-01 21:30 +0000 作者 * Commit 6 C 45 | 2009-09-23 09:07 +0000 René Lévesque * Commit 6 B 46 | 2009-09-14 20:45 +0000 A. U. Thor * Commit 6 A 47 | 2009-09-06 08:23 +0000 Max Power * Commit 5 E 48 | 2009-08-28 20:01 +0000 Jørgen Thygesen Brahe * Commit 5 D 49 | 2009-08-20 07:39 +0000 作者 * Commit 5 C 50 | 2009-08-11 19:17 +0000 René Lévesque * Commit 5 B 51 | 2009-08-03 06:54 +0000 A. U. Thor * Commit 5 A 52 | [main] b45b5704c34dbd4c5fd89d58d45238ad136ae166 - commit 1 of 38 47% 53 | EOF 54 | -------------------------------------------------------------------------------- /test/refs/branch-tag-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=18 7 | 8 | steps ' 9 | :save-display refs-initial.screen 10 | ' 11 | 12 | in_work_dir create_repo_from_tgz "$base_dir/files/refs-repo.tgz" 13 | in_work_dir git branch v2.0 v2.0.1 14 | 15 | test_tig refs 16 | 17 | assert_equals 'refs-initial.screen' < [refs/my-raw-ref2] Initial commit 37 | 38 | 39 | 40 | 41 | 42 | 43 | [main] 174877369ea7af366da2ebcedd63d7a00d8046ea - commit 1 of 1 100% 44 | EOF 45 | 46 | assert_equals 'refs.screen' < file 24 | git add file 25 | git_commit -m "committed" 26 | cd "$pwd" 27 | } 28 | git clone "$REMOTE_REPO" . 29 | } 30 | 31 | test_tig 32 | 33 | assert_equals 'initial.screen' < committe 40 | [main] 6b55d08be93000f4bdf67f74177ab14f590910d4 - commit 1 of 1 100% 41 | EOF 42 | -------------------------------------------------------------------------------- /test/script/comment-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=5 7 | 8 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 9 | 10 | steps ' 11 | :set line-graphics = ascii 12 | # comment 13 | :save-display main.screen 14 | ' 15 | 16 | test_tig 17 | 18 | assert_equals main.screen < @sh -c 'echo "view not closed" > "$HOME/$view_open_file"' 29 | EOF 30 | 31 | test_tig_script 'view-close-no-quit-should-not-close-tig' ' 32 | :view-close-no-quit 33 | 34 | ' 35 | 36 | assert_equals "$view_open_file" < @sh -c 'echo "view not closed" > "$HOME/$view_closed_file"' 45 | EOF 46 | 47 | test_tig_script 'view-close-should-close-tig' ' 48 | :view-close 49 | 50 | ' 51 | 52 | assert_equals "$view_closed_file" < stderr 56 | -------------------------------------------------------------------------------- /test/stage/gh-410-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=12 7 | 8 | steps ' 9 | :save-display status-before.screen 10 | 11 | :5 12 | :enter 13 | :maximize 14 | :save-display unstaged-changes.screen 15 | 16 | :10 17 | :stage-update-line 18 | :save-display status-after.screen 19 | ' 20 | 21 | git_init 22 | 23 | test_setup_work_dir() 24 | { 25 | printf 'Hello\n' > hello.txt 26 | git add . 27 | git_commit -m "first commit" 28 | printf 'Hello2\n' >> hello.txt 29 | } 30 | 31 | test_tig status 32 | 33 | assert_equals 'status-before.screen' <' to jump to file diff - line 1 of 10 100% 59 | EOF 60 | 61 | assert_equals 'status-after.screen' <' to jump to file diff - line 1 of 107 5% 44 | EOF 45 | 46 | assert_equals 'maximized.screen' <' to jump to file diff - line 1 of 107 9% 58 | EOF 59 | -------------------------------------------------------------------------------- /test/stage/split-chunk-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=35 7 | 8 | steps ' 9 | :6 10 | :enter 11 | :maximize 12 | :save-display default-diff.screen 13 | 14 | :12 15 | :stage-split-chunk 16 | :save-display split-diff.screen 17 | ' 18 | 19 | in_work_dir create_dirty_workdir 20 | in_work_dir sh -c 'printf "a CHANGED\n1\n2\nedited-too\n4\n5\nedited-too\n7\n8" > a' 21 | 22 | test_tig status 23 | 24 | assert_equals 'default-diff.screen' <' to jump to file diff - line 1 of 25 100% 59 | EOF 60 | 61 | assert_equals 'split-diff.screen' < "stashed-file-$i" 13 | git stash save -q -u "Stash #$i" 14 | done 15 | } 16 | 17 | steps ' 18 | :save-display position.screen 19 | ' 20 | 21 | tigrc <> bench/README.md 34 | } 35 | 36 | test_exec_work_dir setup_submodule_project 37 | work_dir="$work_dir/bench/common/src" 38 | 39 | test_tig status 40 | 41 | assert_vars 1 42 | 43 | assert_equals 'status.screen' <> "$output_dir/$work_dir/README.md" 31 | } 32 | 33 | test_exec_work_dir setup_worktree_project 34 | work_dir="$work_dir/common/src" 35 | 36 | test_tig status 37 | 38 | assert_vars 1 39 | 40 | assert_equals 'status.screen' < stderr 22 | 23 | assert_equals stderr < $HOME/shell-command.txt" 8 | EOF 9 | 10 | steps ' 11 | 1 12 | ' 13 | 14 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 15 | test_tig 16 | 17 | assert_equals 'shell-command.txt' < $HOME/shell-command.txt" 10 | bind generic 2 !@sh -c 'echo \'single \'\$@ "quoted" \'shell command\' >> $HOME/shell-command.txt' 11 | 12 | bind generic 3 :!echo git log "%(prompt Prompt: )" 13 | bind generic 4 :!echo git log -G"%(prompt Prompt: )" 14 | bind generic 5 :!echo git log -G' \' "\" \\\a\b' 15 | bind generic 6 :!echo git log -G"'\' \" \\\a\b" 16 | EOF 17 | 18 | steps " 19 | 1 20 | 2 21 | 22 | 3 23 | |Quoted 'prompt' input| 24 | :save-display quoted-prompt-with-spaces.screen 25 | 4 26 | |\"Mid-quoted\" prompt input| 27 | :save-display mid-quoted-prompt-with-spaces.screen 28 | 5 29 | :save-display single-quoted-arg-with-escaped-chars.screen 30 | 6 31 | :save-display double-quoted-arg-with-escaped-chars.screen 32 | " 33 | 34 | in_work_dir create_repo_from_tgz "$base_dir/files/scala-js-benchmarks.tgz" 35 | test_tig 36 | 37 | assert_equals stderr < stderr 20 | 21 | assert_equals stderr <> "$out_file" 24 | fi 25 | ;; 26 | *) 27 | if [ -e "$out_file" ]; then 28 | printf '%s\n' "$line" >> "$out_file" 29 | fi 30 | ;; 31 | esac 32 | done < "$base_dir/../doc/tigrc.5.adoc" 33 | 34 | # Create files used by the `source` example 35 | mkdir -p .tig 36 | touch .tig/colorscheme.tigrc .tig/keybindings.tigrc 37 | 38 | tigrc <' 20 | echo "bind generic @sh -c 'echo $name >> $HOME/$TEST_NAME.out'" > "$path" 21 | test_tig status 22 | printf '%s\n' "$name" > "$TEST_NAME.out.expected" 23 | assert_equals "$TEST_NAME.out" < "$TEST_NAME.out.expected" 24 | assert_equals "$TEST_NAME.stderr" < /dev/null 25 | } 26 | 27 | unset XDG_CONFIG_HOME 28 | 29 | check .tigrc 30 | check .config/tig/config 31 | check .config/tig/config XDG_CONFIG_HOME="$HOME" 32 | check etc/tig/config XDG_CONFIG_HOME="$HOME/etc" 33 | -------------------------------------------------------------------------------- /test/tools/setup-conflict.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libgit.sh 4 | 5 | git reset --hard 6 | 7 | change() { 8 | printf '%s\n' "$*" > conflict-file 9 | git add conflict-file 10 | git_commit --message="Change: $*" 11 | } 12 | 13 | change "a" 14 | change "b" 15 | 16 | git branch conflict-master 17 | git branch conflict-branch 18 | 19 | git checkout conflict-master 20 | change "c" 21 | change "c'" 22 | 23 | git checkout conflict-branch 24 | change "d" 25 | change "d'" 26 | 27 | git checkout conflict-master 28 | git merge conflict-branch || true 29 | -------------------------------------------------------------------------------- /test/tools/show-results.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Aggregate test results. 4 | # Usage: $0 5 | # 6 | # Copyright (c) 2006-2025 Jonas Fonseca 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License as 10 | # published by the Free Software Foundation; either version 2 of 11 | # the License, or (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | set -eu 19 | if [ -n "${BASH_VERSION:-}" ]; then 20 | set -o pipefail 21 | IFS=$' \n\t' 22 | fi 23 | 24 | tests="$(find test/ -name ".test-result" | grep -c . || true)" 25 | asserts="$(find test/ -name ".test-result" -exec cat -- "{}" \; | grep -c '^ *\[\(OK\|FAIL\)\]' || true)" 26 | failures="$(find test/ -name ".test-result" -exec cat -- "{}" \; | grep -c '^ *\[FAIL\]' || true)" 27 | skipped="$(find test/ -name ".test-skipped" | grep -c . || true)" 28 | todos="$(find test/ \( -name ".test-skipped" -or -name ".test-skipped-subtest-*" \) -exec cat -- "{}" + | grep -c '^\[TODO\]' || true)" 29 | 30 | if [ "$failures" = 0 ]; then 31 | printf "Passed %d assertions in %d tests" "$asserts" "$tests" 32 | else 33 | printf "Failed %d of %d assertions in %d tests" "$failures" "$asserts" "$tests" 34 | fi 35 | 36 | if [ "$skipped" != 0 ]; then 37 | todo_text="" 38 | if [ "$todos" != 0 ]; then 39 | todo_text=", $todos as todos" 40 | fi 41 | printf " (%d skipped%s)" "$skipped" "$todo_text" 42 | fi 43 | 44 | printf '\n' 45 | exit "$failures" 46 | -------------------------------------------------------------------------------- /test/tools/valgrind-Darwin.supp: -------------------------------------------------------------------------------- 1 | { 2 | darwin_libsystem_wordexp 3 | Memcheck:Cond 4 | fun:strstr 5 | fun:wordexp 6 | fun:path_expand 7 | ... 8 | fun:main 9 | } 10 | -------------------------------------------------------------------------------- /test/tree/file-name-test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . libtest.sh 4 | . libgit.sh 5 | 6 | export LINES=15 7 | export COLUMNS=80 8 | 9 | steps ' 10 | :set vertical-split = no 11 | 12 | :view-tree 13 | :save-display root-dir.screen 14 | 15 | :enter 16 | :save-display first-child-dir.screen 17 | :enter 18 | 19 | :3 20 | :enter 21 | :save-display second-child-dir.screen 22 | 23 | :3 24 | :enter 25 | :save-display second-child-dir-first-file.screen 26 | ' 27 | 28 | test_setup_work_dir() 29 | { 30 | mkdir -p -- "-- foo bar" 31 | touch -- "-- foo bar/-- boo far" 32 | touch -- "-- foo bar/as测试asd" 33 | 34 | mkdir -p -- "-foo" 35 | printf 'OK\n' > "-foo/-bar" 36 | touch -- "-foo/-bar" 37 | 38 | git add . 39 | git_commit -m "Initial" 40 | } 41 | 42 | git_init 43 | test_tig 44 | 45 | assert_equals 'root-dir.screen' < 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License as 10 | # published by the Free Software Foundation; either version 2 of 11 | # the License, or (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | root="$(git rev-parse --show-cdup)" 19 | NEWS="${root}NEWS.adoc" 20 | README="${root}README.adoc" 21 | from="$(sed -n '7,/^tig-/p' < "$NEWS" | tail -n 1 | cut -d' ' -f 1)" 22 | to="${1-HEAD}" 23 | short= 24 | 25 | test -n "$(git rev-list --skip=50 $from..$to)" && short=-s 26 | 27 | cat < 27 | # 28 | # Copying and distribution of this file, with or without modification, are 29 | # permitted in any medium without royalty provided the copyright notice 30 | # and this notice are preserved. This file is offered as-is, without any 31 | # warranty. 32 | 33 | #serial 1 34 | 35 | AC_DEFUN([AX_REQUIRE_DEFINED], [dnl 36 | m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) 37 | ])dnl AX_REQUIRE_DEFINED 38 | -------------------------------------------------------------------------------- /tools/doc-gen.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | 14 | #include "tig/tig.h" 15 | #include "tig/request.h" 16 | #include "tig/util.h" 17 | 18 | struct doc_action_iterator { 19 | bool end_group; 20 | const char *group; 21 | }; 22 | 23 | static void 24 | doc_action_group_name_print(const char *group) 25 | { 26 | printf("%s\n", group); 27 | while (*group++) 28 | printf("^"); 29 | printf("\n\n"); 30 | } 31 | 32 | static void 33 | doc_action_table_print(bool start) 34 | { 35 | if (start) 36 | printf("[frame=\"none\",grid=\"none\",cols=\"25group != group) { 46 | if (iterator->end_group) { 47 | doc_action_table_print(false); 48 | printf("\n"); 49 | } 50 | 51 | doc_action_group_name_print(group); 52 | doc_action_table_print(true); 53 | 54 | iterator->group = group; 55 | iterator->end_group = true; 56 | } 57 | 58 | printf("|%-24s|%s\n", enum_name(req_info->name), req_info->help); 59 | return true; 60 | } 61 | 62 | static void 63 | doc_actions_print(void) 64 | { 65 | struct doc_action_iterator iterator = { false }; 66 | 67 | foreach_request(doc_action_print, &iterator); 68 | doc_action_table_print(false); 69 | } 70 | 71 | int 72 | main(int argc, const char *argv[]) 73 | { 74 | int i; 75 | 76 | for (i = 1; i < argc; i++) { 77 | if (!strcmp(argv[i], "actions")) 78 | doc_actions_print(); 79 | } 80 | 81 | return EXIT_SUCCESS; 82 | } 83 | 84 | /* vim: set ts=8 sw=8 noexpandtab: */ 85 | -------------------------------------------------------------------------------- /tools/header.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006-2025 Jonas Fonseca 2 | * 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of the GNU General Public License as 5 | * published by the Free Software Foundation; either version 2 of 6 | * the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | */ 13 | -------------------------------------------------------------------------------- /tools/iconv.m4: -------------------------------------------------------------------------------- 1 | dnl From Bruno Haible. 2 | AC_DEFUN([AM_ICONV], 3 | [ 4 | dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and 5 | dnl those with the standalone portable GNU libiconv installed). 6 | 7 | AC_ARG_WITH([libiconv], 8 | [ --with-libiconv=DIR search for libiconv in DIR/include and DIR/lib], [ 9 | for dir in `echo "$withval" | tr : ' '`; do 10 | if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi 11 | if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi 12 | done 13 | ]) 14 | 15 | AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ 16 | am_cv_func_iconv="no, consider installing GNU libiconv" 17 | am_cv_lib_iconv=no 18 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 19 | #include ]], [[iconv_t cd = iconv_open("",""); 20 | iconv(cd,NULL,NULL,NULL,NULL); 21 | iconv_close(cd);]])],[am_cv_func_iconv=yes],[]) 22 | if test "$am_cv_func_iconv" != yes; then 23 | am_save_LIBS="$LIBS" 24 | LIBS="$LIBS -liconv" 25 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 26 | #include ]], [[iconv_t cd = iconv_open("",""); 27 | iconv(cd,NULL,NULL,NULL,NULL); 28 | iconv_close(cd);]])],[am_cv_lib_iconv=yes 29 | am_cv_func_iconv=yes],[]) 30 | LIBS="$am_save_LIBS" 31 | fi 32 | ]) 33 | if test "$am_cv_func_iconv" = yes; then 34 | AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) 35 | AC_MSG_CHECKING([for iconv declaration]) 36 | AC_CACHE_VAL(am_cv_proto_iconv, [ 37 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 38 | #include 39 | #include 40 | extern 41 | #ifdef __cplusplus 42 | "C" 43 | #endif 44 | #if defined(__STDC__) || defined(__cplusplus) 45 | size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); 46 | #else 47 | size_t iconv(); 48 | #endif 49 | ]], [[]])],[am_cv_proto_iconv_arg1=""],[am_cv_proto_iconv_arg1="const"]) 50 | am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) 51 | am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` 52 | AC_MSG_RESULT([$]{ac_t:- 53 | }[$]am_cv_proto_iconv) 54 | AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, 55 | [Define as const if the declaration of iconv() needs const.]) 56 | else 57 | AC_MSG_FAILURE([iconv() not found. Please install libiconv and use --with-libiconv=/path/to/dir.],[1]) 58 | fi 59 | if test "$am_cv_lib_iconv" = yes; then 60 | LIBS="$LIBS -liconv" 61 | fi 62 | ]) 63 | -------------------------------------------------------------------------------- /tools/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Install data or executable file. 4 | # 5 | # Usage: $0 {data|bin} src dest 6 | # 7 | # Copyright (c) 2006-2025 Jonas Fonseca 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License as 11 | # published by the Free Software Foundation; either version 2 of 12 | # the License, or (at your option) any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | 19 | set -e 20 | 21 | data="$1" 22 | src="$2" 23 | dest="$3" 24 | mode=0755 25 | trash= 26 | 27 | case "$data" in data) 28 | mode=0644 29 | esac 30 | 31 | install -d "$dest" 32 | 33 | if [ "$V" = "@" ]; then 34 | echo "$src -> $dest" 35 | fi 36 | 37 | # Replace fake /etc-path 38 | case "$src" in doc/*) 39 | dest="$dest/$(basename "$src")" 40 | sed "s#++SYSCONFDIR++#${sysconfdir}#" < "$src" > "$src+" 41 | trash="$src+" 42 | src="$src+" 43 | esac 44 | 45 | install -p -m "$mode" "$src" "$dest" 46 | 47 | if [ -n "$trash" ]; then 48 | rm -f "$trash" 49 | fi 50 | -------------------------------------------------------------------------------- /tools/make-builtin-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Generate code for including a copy of the default tigrc inside the 4 | # binary. 5 | # 6 | # Usage: $0 /path/to/tigrc 7 | # 8 | # Copyright (c) 2006-2025 Jonas Fonseca 9 | # 10 | # This program is free software; you can redistribute it and/or 11 | # modify it under the terms of the GNU General Public License as 12 | # published by the Free Software Foundation; either version 2 of 13 | # the License, or (at your option) any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | TIGRC="${1:-tigrc}" 21 | 22 | read_tigrc() { 23 | if test -z "$NO_BUILTIN_TIGRC"; then 24 | sed 's/[[:space:]]*#.*//' "$TIGRC" | sed 's,\\,\\\\,g' | sed 's,",\\",g' | sed 's/ \+/ /g' 25 | else 26 | echo '#' 27 | fi 28 | } 29 | 30 | echo "/* Generated by $0 */" 31 | echo "const char *builtin_config =" 32 | 33 | read_tigrc | while read -r line; do 34 | case "$line" in 35 | "") : ignore ;; 36 | *) printf ' "%s\\n"\n' "$line" 37 | esac 38 | done 39 | 40 | echo ";" 41 | -------------------------------------------------------------------------------- /tools/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Script for preparing a release or updating the release branch. 4 | # Usage: $0 version 5 | # 6 | # Copyright (c) 2006-2025 Jonas Fonseca 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License as 10 | # published by the Free Software Foundation; either version 2 of 11 | # the License, or (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | 18 | set -e 19 | set -x 20 | 21 | VERSION="$1" 22 | 23 | if which gsed >/dev/null; then SED=gsed; else SED=sed; fi 24 | 25 | TAG="tig-$VERSION" 26 | TITLE="$TAG\n$(echo "$TAG" | $SED 's/./-/g')" 27 | NEWS="NEWS.adoc" 28 | 29 | # Require a clean repository. 30 | git update-index --refresh 31 | git diff-index --quiet HEAD 32 | 33 | if test -n "$VERSION"; then 34 | # Get a sane starting point. 35 | test "$(git symbolic-ref HEAD)" = "refs/heads/master" || 36 | git checkout master 37 | 38 | # Update files which should reference the version. 39 | $SED -i "s/VERSION\s*=\s*[0-9.]\+/VERSION = $VERSION/" Makefile 40 | $SED -i "s#tig-[0-9.]\+[0-9]\+#tig-$VERSION#g" INSTALL.adoc 41 | perl -pi -e 's/^master$/RELEASE_TITLE/ms' "$NEWS" 42 | perl -pi -e 's/^RELEASE_TITLE.*/RELEASE_TITLE/ms' "$NEWS" 43 | perl -pi -e "s/^RELEASE_TITLE.*/$TITLE/" "$NEWS" 44 | 45 | # Check for typos. 46 | make spell-check 47 | 48 | # Last review. 49 | ${EDITOR:-vi} "$NEWS" 50 | 51 | # Create release commit and tag. 52 | git commit -a -m "$TAG" 53 | git tag -s -m "tig version $VERSION" "$TAG" 54 | 55 | # Prepare release announcement file. 56 | ./tools/announcement.sh "$TAG" > "$TAG.txt" 57 | 58 | # Set version for the Makefile 59 | export DIST_VERSION="$VERSION" 60 | else 61 | # Get meaningful version for the update message. 62 | TAG="$(git describe)" 63 | fi 64 | 65 | # Update the release branch. 66 | git checkout release 67 | HEAD="$(git rev-parse release)" 68 | git merge --ff master 69 | if test -n "$(git rev-list -1 release ^$HEAD)"; then 70 | make veryclean doc-man doc-html sysconfdir=++SYSCONFDIR++ 71 | git commit -a -m "Update for version $TAG" 72 | fi 73 | 74 | if test -n "$VERSION"; then 75 | # Create the tarball. 76 | make dist 77 | fi 78 | 79 | # Done. 80 | git checkout master 81 | -------------------------------------------------------------------------------- /tools/travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | 6 | build_config_make() { 7 | cp contrib/config.make . 8 | make all-debug 9 | make update-docs && git diff --exit-code 10 | make test 11 | 12 | make prefix=/tmp/bare-prefix install install-doc 13 | /tmp/bare-prefix/bin/tig --version 14 | make prefix=/tmp/bare-prefix uninstall 15 | test ! -d /tmp/bare-prefix 16 | 17 | make distclean 18 | } 19 | 20 | build_autoconf() { 21 | make dist 22 | ./configure --prefix=/tmp/conf-prefix 23 | make V=1 TEST_SHELL=bash all test 24 | 25 | make install install-doc 26 | /tmp/conf-prefix/bin/tig --version 27 | make uninstall 28 | test ! -d /tmp/conf-prefix 29 | 30 | make DESTDIR=/tmp/bare-destdir install install-doc 31 | /tmp/bare-destdir/tmp/conf-prefix/bin/tig --version 32 | make DESTDIR=/tmp/bare-destdir uninstall 33 | test ! -d /tmp/bare-destdir 34 | 35 | make clean 36 | } 37 | 38 | build_address_sanitizer() { 39 | cp contrib/config.make . 40 | make test-address-sanitizer 41 | } 42 | 43 | build_valgrind() { 44 | cp contrib/config.make . 45 | make all-debug test TEST_OPTS=valgrind 46 | } 47 | 48 | case "$TIG_BUILD" in 49 | config.make) build_config_make ;; 50 | autoconf) build_autoconf ;; 51 | address-sanitizer) build_address_sanitizer ;; 52 | valgrind) build_valgrind ;; 53 | 54 | *) 55 | echo "Unknown config: $TIG_BUILD" 56 | exit 1 57 | esac 58 | -------------------------------------------------------------------------------- /tools/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Uninstall data or executable file. 4 | # 5 | # Usage: $0 dest 6 | # 7 | # Copyright (c) 2006-2025 Jonas Fonseca 8 | # 9 | # This program is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU General Public License as 11 | # published by the Free Software Foundation; either version 2 of 12 | # the License, or (at your option) any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | 19 | set -e 20 | 21 | file="$1" 22 | dir="$(dirname "$file")" 23 | 24 | if [ -d "$file" -a "$dir" = "tig" ]; then 25 | rm -rf "$file" 26 | elif [ -f "$file" ]; then 27 | rm -f "$file" 28 | fi 29 | 30 | if [ -d "$dir" ]; then 31 | set +e 32 | rmdir -p "$dir" 2>/dev/null 33 | fi 34 | 35 | echo "$file" 36 | --------------------------------------------------------------------------------