--- warning: DO NOT CHANGE THIS MANUALLY, THIS IS GENERATED BY https://github.com/duckdb/community-extensions repository, check README there title: duck_tails excerpt: | DuckDB Community Extensions Smart Development Intelligence for DuckDB - Git-aware data analysis capabilities that allow querying git history, accessing files at any revision, and performing version-aware data analysis with SQL. extension: name: duck_tails description: Smart Development Intelligence for DuckDB - Git-aware data analysis capabilities that allow querying git history, accessing files at any revision, and performing version-aware data analysis with SQL. version: 1.9.0 language: C++ build: cmake license: MIT requires_toolchains: vcpkg excluded_platforms: wasm_mvp;wasm_eh;wasm_threads maintainers: - teaguesterling repo: github: teaguesterling/duck_tails # ref and ref_next are deliberately the SAME commit (v1.9.0, 2b20b7d). duck_tails # now builds from ONE source tree against both DuckDB lines: the v2.0 removal of # TableFunction::named_parameters is handled by named_parameter_compat.hpp, which # declares via GetSignature().WithTypedKwargs() on v2.0 and the flat map on v1.5. # # Evidence: clean local builds of this tree against v2.0.0 (d54cbbe3) and v1.5.6, # each with `All tests passed (1479 assertions in 74 test cases)`. ref: 2b20b7d21c864817538e347e82f70fed76598f4d ref_next: 2b20b7d21c864817538e347e82f70fed76598f4d docs: hello_world: | -- Load the extension LOAD 'duck_tails'; -- Query git history (defaults to current directory) SELECT commit_hash, author_name, message, author_date FROM git_log() LIMIT 5; -- Access files from git repository at specific revisions. -- Both forms are valid and read the same file; ?ref= is the canonical form. SELECT * FROM read_csv('git://data/sales.csv?ref=HEAD'); SELECT * FROM read_csv('git://data/sales.csv@HEAD'); -- Compare data between commits SELECT (SELECT count(*) FROM read_csv('git://data/sales.csv?ref=HEAD')) AS current_count, (SELECT count(*) FROM read_csv('git://data/sales.csv?ref=HEAD~1')) AS previous_count; -- Analyze text differences SELECT * FROM read_git_diff('git://README.md@HEAD', 'git://README.md@HEAD~1'); extended_description: | Duck Tails brings git-aware data analysis capabilities to DuckDB, enabling sophisticated version-controlled data workflows. The extension provides three core capabilities: **Git Filesystem Access**: Use the `git://` protocol to access any file in your git repository at any commit, branch, or tag. This allows you to query historical data states, compare versions, and perform temporal analysis directly in SQL. **Repository Metadata Queries**: Query git repository information directly with table functions like `git_log()`, `git_branches()`, and `git_tags()`. Analyze commit histories, track development patterns, and integrate repository metadata into your analytical workflows. **Text Diff Analysis**: Comprehensive text diffing capabilities with functions like `diff_text()`, `read_git_diff()`, and `text_diff_stats()`. Analyze changes between file versions, track configuration drift, and perform code change analysis. Key functions include: - `git_log([path])` - Query commit history - `git_branches([path])` - List repository branches - `git_tags([path])` - List repository tags - `diff_text(old, new)` - Compute text differences - `read_git_diff(file1, [file2])` - Structured diff analysis - `text_diff_lines(diff)` - Parse diff into line-by-line changes - `text_diff_stats(old, new)` - Diff statistics and metrics The extension supports mixed file systems, allowing you to combine git://, local files, S3, and other DuckDB-supported protocols in a single query. Built with libgit2 for robust git operations and comprehensive error handling. extension_star_count: 29 extension_star_count_pretty: 29 extension_download_count: 2548 extension_download_count_pretty: 2.5k image: '/images/community_extensions/social_preview/preview_community_extension_duck_tails.png' layout: community_extension_doc --- ### Compatibility Matrix This table covers all DuckDB releases that have not reached [end-of-life](https://duckdb.org/release_calendar), including LTS releases, and shows the 2 most recent patch releases of each. Older patch releases are not listed, but the extension may be available for them as well.
| Platform | 1.4.4 | 1.4.5 | 1.5.5 | 1.5.6 | 2.0.0 | | :--- | :---: | :---: | :---: | :---: | :---: | | Linux AMD64 | ✅ | ✅ | ✅ | ✅ | ✅ | | Linux ARM64 | ✅ | ✅ | ✅ | ✅ | ✅ | | macOS AMD64 | ✅ | ✅ | ✅ | ✅ | ❌ | | macOS ARM64 | ✅ | ✅ | ✅ | ✅ | ✅ | | Windows AMD64 | ❌ | ❌ | ✅ | ✅ | ✅ | | Windows ARM64 | ❌ | ❌ | ❌ | ❌ | ❌ | | WebAssembly | ❌ | ❌ | ❌ | ❌ | ❌ | ### Installing and Loading ```sql INSTALL {{ page.extension.name }} FROM community; LOAD {{ page.extension.name }}; ``` {% if page.docs.hello_world %} ### Example ```sql {{ page.docs.hello_world }}``` {% endif %} {% if page.docs.extended_description %} ### About {{ page.extension.name }} {{ page.docs.extended_description }} {% endif %} ### Added Functions | function_name | function_type | description | comment | examples | |----------------------|---------------|-------------------------------------------------------------------------------------|---------|----------------------------------------------------------------| | diff_lines | scalar | NULL | NULL | | | diff_text | scalar | Compute unified diff between two text strings. | NULL | [diff_text('old text', 'new text')] | | git_blame | table | Show line-by-line git blame annotations for a file. | NULL | [SELECT * FROM git_blame('README.md')] | | git_blame_each | table | NULL | NULL | | | git_blame_hunks | table | Show git blame hunk annotations for a file. | NULL | [SELECT * FROM git_blame_hunks('README.md')] | | git_blame_hunks_each | table | NULL | NULL | | | git_branches | table | List git branches from current directory repository. | NULL | [SELECT * FROM git_branches()] | | git_branches | table | NULL | NULL | | | git_branches_each | table | NULL | NULL | | | git_canonicalize | scalar | Rewrite a deprecated git://path@rev URI into the canonical git://path?ref=rev form. | NULL | [git_canonicalize('git://README.md@HEAD')] | | git_diff_tree | table | Show diff of working tree changes in current repository. | NULL | [SELECT * FROM git_diff_tree()] | | git_diff_tree | table | NULL | NULL | | | git_diff_tree_each | table | NULL | NULL | | | git_log | table | Read git commit log from current directory. | NULL | [SELECT * FROM git_log()] | | git_log | table | NULL | NULL | | | git_log_each | table | NULL | NULL | | | git_parents | table | List parent commits for HEAD in current repository. | NULL | [SELECT * FROM git_parents()] | | git_parents | table | NULL | NULL | | | git_parents_each | table | NULL | NULL | | | git_read | table | NULL | NULL | | | git_read_each | table | NULL | NULL | | | git_status | table | Show working tree status for current directory repository. | NULL | [SELECT * FROM git_status()] | | git_status | table | NULL | NULL | | | git_status_each | table | LATERAL table function to show git working tree status for input repo path. | NULL | [SELECT * FROM repos, LATERAL git_status_each(path)] | | git_tags | table | List git tags from current directory repository. | NULL | [SELECT * FROM git_tags()] | | git_tags | table | NULL | NULL | | | git_tags_each | table | NULL | NULL | | | git_tree | table | List files in git tree for repository path or URI. | NULL | [SELECT * FROM git_tree('.')] | | git_tree | table | NULL | NULL | | | git_tree_each | table | NULL | NULL | | | git_uri | scalar | Construct a canonical git:// URI from repo path, file path, and commit ref. | NULL | [git_uri('.', 'README.md', 'HEAD')] | | read_git_diff | table | NULL | NULL | | | text_diff | scalar | Compute unified diff between two text strings. | NULL | [text_diff('old text', 'new text')] | | text_diff_lines | table | Parse diff string into rows of individual line changes. | NULL | [SELECT * FROM text_diff_lines('@@ -1 +1 @@