@@ -66,13 +66,21 @@ def _pack_source_code(source_location, tar_file_path, docker_file_path, docker_f
6666 original_docker_file_name = os .path .basename (docker_file_path .replace ("\\ " , os .sep ))
6767 ignore_list , ignore_list_size = _load_dockerignore_file (source_location , original_docker_file_name )
6868 common_vcs_ignore_list = {'.git' , '.gitignore' , '.bzr' , 'bzrignore' , '.hg' , '.hgignore' , '.svn' }
69+ # Directories that should be completely excluded (no recursive descent) for performance reasons.
70+ # These typically contain large numbers of files that are not needed for container build context.
71+ build_ignore_dirs = {'.venv' }
6972
7073 def _ignore_check (tarinfo , parent_ignored , parent_matching_rule_index ):
71- # ignore common vcs dir or file
72- if tarinfo .name in common_vcs_ignore_list :
74+ # Ignore common VCS dirs/files by basename so nested instances are handled.
75+ if os . path . basename ( tarinfo .name ) in common_vcs_ignore_list :
7376 logger .warning ("Excluding '%s' based on default ignore rules" , tarinfo .name )
7477 return True , parent_matching_rule_index
7578
79+ # Exclude performance-heavy directories entirely (no traversal) regardless of .dockerignore.
80+ if tarinfo .isdir () and os .path .basename (tarinfo .name ) in build_ignore_dirs :
81+ logger .warning ("Excluding '%s' directory for performance" , os .path .basename (tarinfo .name ))
82+ return True , parent_matching_rule_index
83+
7684 if ignore_list is None :
7785 # if .dockerignore doesn't exists, inherit from parent
7886 # eg, it will ignore the files under .git folder.
@@ -100,7 +108,8 @@ def _ignore_check(tarinfo, parent_ignored, parent_matching_rule_index):
100108 arcname = "" ,
101109 parent_ignored = False ,
102110 parent_matching_rule_index = ignore_list_size ,
103- ignore_check = _ignore_check )
111+ ignore_check = _ignore_check ,
112+ build_ignore_dirs = build_ignore_dirs )
104113
105114 # Add the Dockerfile if it's specified.
106115 # In the case of run, there will be no Dockerfile.
@@ -182,7 +191,8 @@ def _load_dockerignore_file(source_location, original_docker_file_name):
182191 return ignore_list , len (ignore_list )
183192
184193
185- def _archive_file_recursively (tar , name , arcname , parent_ignored , parent_matching_rule_index , ignore_check ):
194+ def _archive_file_recursively (tar , name , arcname , parent_ignored , parent_matching_rule_index ,
195+ ignore_check , build_ignore_dirs ):
186196 # create a TarInfo object from the file
187197 tarinfo = tar .gettarinfo (name , arcname )
188198
@@ -201,12 +211,13 @@ def _archive_file_recursively(tar, name, arcname, parent_ignored, parent_matchin
201211 else :
202212 tar .addfile (tarinfo )
203213
204- # even the dir is ignored, its child items can still be included, so continue to scan
205- if tarinfo .isdir ():
214+ # Even if a dir is ignored by .dockerignore, its children might still be included (Docker semantics),
215+ # so we continue scanning unless it is in our build_ignore_dirs set (performance skip list).
216+ if tarinfo .isdir () and os .path .basename (tarinfo .name ) not in build_ignore_dirs :
206217 for f in os .listdir (name ):
207218 _archive_file_recursively (tar , os .path .join (name , f ), os .path .join (arcname , f ),
208219 parent_ignored = ignored , parent_matching_rule_index = matching_rule_index ,
209- ignore_check = ignore_check )
220+ ignore_check = ignore_check , build_ignore_dirs = build_ignore_dirs )
210221
211222
212223def check_remote_source_code (source_location ):
0 commit comments