Updated: Bash functions to provide repository context for LLM chats

Posted . Visible to the public. Auto-destruct in 60 days

Documented a repomix that allows you to bundle the XML repository context with custom LLM instructions. I have mine located at ~/.config/repomix/instruction.md

Changes

  • I use the Gemini web chat interface quite extensively. One thing that is tedious is giving it all the context it needs to do a proper job. Context engineering is not an easy task, but on the other hand we now have context limits of ~1 million token, which allows us to just dump in everything we have in many cases. And when we do that in the web interface, we can avoid extra costs that would be charged when using the API!
  • The functions below pack your current work (diffs, full repos, or specific commits) into XML/Diff files, which are then load into your clipboard as File Uploads. My workflow with them is something like this:
  • 1. Run `pack_repo_context` in a terminal
  • 2. Open <https://gemini.google.com> in a new tab
  • 3. Press `Ctrl+V`
  • 4. Ask a question
  • 5. Repeat
  • ## Prerequisites
  • * The `xclip` apt package
  • * [repomix](https://github.com/yamadashy/repomix) installed (we use `npx repomix@latest` below)
  • ## Usage
  • | Function | Use Cases |
  • | --- | --- |
  • | **`pack_repo_context`** | Packs the **entire repo** (with some exclusions!) into 1-5 XML files. Can be used for all kind of tasks from "How does this project work?" to large refactors. |
  • | **`debug_repo_context`** | Inspect which files are packed into the XML |
  • | **`pack_git_diff_main`** | Generates a **diff between the current work and `main`**. Can be used for Code reviews, test generation etc. |
  • | **`pack_git_diff_head`** | Generates a **diff of uncommitted changes**. Can be used to get assistance on current work. |
  • | **`pack_git_show`** | Generates a **diff for the last commit** on your current branch. Can sometimes be useful to iterate on already committed work. |
  • ## Configuration
  • ### Bash Functions
  • ```bash
  • # ~/.bashrc or wherever else you place your bash functions
  • IGNORED_BINARY_EXTS=(
  • "png" "jpg" "jpeg" "gif" "ico" "svg"
  • "woff" "woff2" "ttf" "eot"
  • "pdf" "PDF" "d2" "bmml" "xsd" "xsl"
  • "jar" "gz" "map" "enc" "m4v" "yml"
  • "key" "sqlite3" "rdb"
  • )
  • _copy_file_uris() {
  • local uri_list=""
  • local count=0
  • for file_path in "$@"; do
  • if [[ -f "$file_path" ]]; then
  • uri_list="${uri_list}file://$(readlink -f "$file_path")\n"
  • ((count++))
  • fi
  • done
  • if [ $count -eq 0 ]; then
  • echo "No files created or found to copy."
  • return 1
  • fi
  • printf "$uri_list" | head -c -1 | xclip -selection clipboard -t text/uri-list
  • echo "📋 Copied $count file(s) to clipboard."
  • }
  • ___repomix_ignores() {
  • local excludes=""
  • for ext in "${IGNORED_BINARY_EXTS[@]}"; do
  • excludes="$excludes,**/*.$ext"
  • done
  • echo "${excludes:1}"
  • }
  • ___git_excludes() {
  • excludes=()
  • for ext in "${IGNORED_BINARY_EXTS[@]}"; do
  • excludes+=(":!*.$ext")
  • done
  • }
  • pack_repo_context() {
  • local dyn_ignores=$(___repomix_ignores)
  • local out_dir="tmp"
  • local base_name="repomix-out"
  • mkdir -p "$out_dir"
  • rm -f "$out_dir/$base_name"*.xml
  • npx repomix@latest \
  • --ignore "$dyn_ignores" \
  • --output "$out_dir/$base_name.xml" \
  • --split-output "2mb" \
  • --quiet
  • local files=()
  • if compgen -G "$out_dir/$base_name*.xml" > /dev/null; then
  • files=("$out_dir/$base_name"*.xml)
  • else
  • files=("$out_dir/$base_name.xml")
  • fi
  • _copy_file_uris "${files[@]}"
  • }
  • debug_repo_context() {
  • local dyn_ignores=$(___repomix_ignores)
  • echo "Analyzing repository context (Dry Run)..."
  • npx repomix@latest \
  • --ignore "$dyn_ignores" \
  • --token-count-tree \
  • --no-files \
  • --output /dev/null \
  • --top-files-len 20
  • }
  • pack_git_diff_main() {
  • local out_file="tmp/git-diff-main.diff"
  • local excludes
  • ___git_excludes
  • mkdir -p tmp
  • git diff main -- "${excludes[@]}" > "$out_file"
  • _copy_file_uris "$out_file"
  • }
  • pack_git_diff_head() {
  • local out_file="tmp/git-diff-head.diff"
  • local excludes
  • ___git_excludes
  • mkdir -p tmp
  • git diff HEAD -- "${excludes[@]}" > "$out_file"
  • _copy_file_uris "$out_file"
  • }
  • pack_git_show() {
  • local out_file="tmp/git-show.diff"
  • local excludes
  • ___git_excludes
  • mkdir -p tmp
  • if [ $# -eq 0 ]; then
  • git show -- "${excludes[@]}" > "$out_file"
  • else
  • git show "$@" -- "${excludes[@]}" > "$out_file"
  • fi
  • _copy_file_uris "$out_file"
  • }
  • ```
  • ### Repomix Config
  • LLMs parse XML quite well. Reduce whitespace and comments to save tokens. Ignore some files explicitly.
  • ```json
  • # ~/.config/repomix/repomix.config.json
  • {
  • "output": {
  • "dir": "tmp",
  • "style": "xml",
  • "removeEmptyLines": true,
  • "removeComments": true,
  • "parsableStyle": true,
  • "compress": false
  • },
  • "ignore": {
  • "customPatterns": [
  • "db/migrate/*.rb",
  • ".env*",
  • "bin/*",
  • "public/packs/*",
  • "public/packs-test/*",
  • "spec/fixtures/*",
  • "gurney.yml",
  • ".geordi.yml",
  • "**/*/*.min.css",
  • "**/*/*.min.js"
  • ]
  • }
  • }
  • ```
  • +> [NOTE]
  • +> Use the [output.instructionFilePath](https://github.com/yamadashy/repomix?tab=readme-ov-file#custom-instruction) option to always include a file containing instructions for the LLM. _Make no mistakes_.
  • +
  • ### Alternative bash alias
  • The bash functions above are only an iteration from my previous bash alias. It became quite unreadable over time and and copies the raw XML to the clipboard (not files). If you prefer less magic in your .bashrc, feel free to use it instead:
  • ```sh
  • alias pack_repo_context='npx repomix@latest --remove-empty-lines --remove-comments --ignore "db/migrate/*.rb,.env*,bin/*,*/**/*.key,*/**/*.sqlite3,*/**/*.svg,*/**/*.woff2,*/**/*.eot,*/**/*.ttf,*/**/*.woff,*/**/*.rdb,*.rdb,*/**/*.gif,*/**/*.jpg,*/**/*.jpeg,*/**/*.d2,*/**/*.bmml,*/**/*.xsd,*/**/*.xsl,*/**/*.jar,*/**/*.gz*,*/**/*.map,public/packs/*,public/packs-test/*,spec/fixtures/*,**/*.png,**/*.pdf,**/*.jpg,**/*.ico,spec/**/*.yml,**/*.enc,**/*.PDF,gurney.yml,.geordi.yml," -o tmp/repomix.xml --quiet --copy'
  • ```
Profile picture of Michael Leimstädtner
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Michael Leimstädtner to makandra dev (2026-02-03 15:07)