@@ -44,6 +44,7 @@ set -euo pipefail
4444# - docs/codebase-overview/
4545# - docs/prompts/
4646# - project.code-workspace (if not already present)
47+ # - .gitignore content (managed section with begin/end markers)
4748#
4849# Exit codes:
4950# 0 - All files copied successfully
@@ -74,6 +75,11 @@ ADR_TEMPLATE="${REPO_ROOT}/docs/adr/ADR-nnn_Any_Decision_Record_Template.md"
7475DOCS_CODEBASE_OVERVIEW=" ${REPO_ROOT} /docs/codebase-overview"
7576DOCS_PROMPTS=" ${REPO_ROOT} /docs/prompts"
7677WORKSPACE_FILE=" ${REPO_ROOT} /project.code-workspace"
78+ GITIGNORE_PROMPTFILES=" ${REPO_ROOT} /.gitignore.promptfiles"
79+
80+ # Begin/end markers for managed .gitignore content
81+ GITIGNORE_BEGIN_MARKER=" # >>> promptfiles-copilot managed content - DO NOT EDIT BELOW THIS LINE >>>"
82+ GITIGNORE_END_MARKER=" # <<< promptfiles-copilot managed content - DO NOT EDIT ABOVE THIS LINE <<<"
7783
7884# Default instruction files (glue layer)
7985DEFAULT_INSTRUCTIONS=(" docker" " makefile" " readme" " shell" )
@@ -244,6 +250,7 @@ function main() {
244250 copy-docs-codebase-overview " ${destination} "
245251 copy-docs-prompts " ${destination} "
246252 copy-workspace-file " ${destination} "
253+ update-gitignore " ${destination} "
247254
248255 echo
249256 echo " Done. Assets copied to ${destination} "
@@ -593,6 +600,62 @@ function copy-workspace-file() {
593600 fi
594601}
595602
603+ # Update .gitignore with promptfiles managed content.
604+ # Creates .gitignore if it doesn't exist, or updates the managed section if it does.
605+ # Arguments (provided as function parameters):
606+ # $1=[destination directory path]
607+ function update-gitignore() {
608+
609+ local dest_gitignore=" $1 /.gitignore"
610+ local source_content
611+ source_content=$( cat " ${GITIGNORE_PROMPTFILES} " )
612+
613+ if [[ ! -f " ${dest_gitignore} " ]]; then
614+ # No .gitignore exists, create it with markers and content
615+ print-info " Creating .gitignore with promptfiles managed content"
616+ {
617+ echo " ${GITIGNORE_BEGIN_MARKER} "
618+ echo " ${source_content} "
619+ echo " ${GITIGNORE_END_MARKER} "
620+ } > " ${dest_gitignore} "
621+ else
622+ # .gitignore exists, check for existing managed content
623+ if grep -qF " ${GITIGNORE_BEGIN_MARKER} " " ${dest_gitignore} " ; then
624+ # Remove existing managed content (between markers, inclusive)
625+ print-info " Updating promptfiles managed content in .gitignore"
626+ local temp_file
627+ temp_file=$( mktemp)
628+ awk -v begin=" ${GITIGNORE_BEGIN_MARKER} " -v end=" ${GITIGNORE_END_MARKER} " '
629+ $0 == begin { skip = 1; next }
630+ $0 == end { skip = 0; next }
631+ !skip { print }
632+ ' " ${dest_gitignore} " > " ${temp_file} "
633+ # Remove trailing blank lines from temp file
634+ sed -i ' ' -e :a -e ' /^\n*$/{$d;N;ba' -e ' }' " ${temp_file} " 2> /dev/null || sed -i -e :a -e ' /^\n*$/{$d;N;ba' -e ' }' " ${temp_file} "
635+ # Write back with new managed content
636+ {
637+ cat " ${temp_file} "
638+ echo " "
639+ echo " ${GITIGNORE_BEGIN_MARKER} "
640+ echo " ${source_content} "
641+ echo " ${GITIGNORE_END_MARKER} "
642+ } > " ${dest_gitignore} "
643+ rm -f " ${temp_file} "
644+ else
645+ # No managed content exists, append it
646+ print-info " Appending promptfiles managed content to .gitignore"
647+ {
648+ echo " "
649+ echo " ${GITIGNORE_BEGIN_MARKER} "
650+ echo " ${source_content} "
651+ echo " ${GITIGNORE_END_MARKER} "
652+ } >> " ${dest_gitignore} "
653+ fi
654+ fi
655+
656+ return 0
657+ }
658+
596659# Copy a directory without bringing across any nested .git metadata.
597660# Arguments (provided as function parameters):
598661# $1=[source directory path]
0 commit comments