@@ -263,6 +263,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,
263263struct extra_file_info {
264264 char * base ;
265265 struct stat stat ;
266+ void * content ;
266267};
267268
268269int write_archive_entries (struct archiver_args * args ,
@@ -337,7 +338,13 @@ int write_archive_entries(struct archiver_args *args,
337338 strbuf_addstr (& path_in_archive , basename (path ));
338339
339340 strbuf_reset (& content );
340- if (strbuf_read_file (& content , path , info -> stat .st_size ) < 0 )
341+ if (info -> content )
342+ err = write_entry (args , & fake_oid , path_in_archive .buf ,
343+ path_in_archive .len ,
344+ info -> stat .st_mode ,
345+ info -> content , info -> stat .st_size );
346+ else if (strbuf_read_file (& content , path ,
347+ info -> stat .st_size ) < 0 )
341348 err = error_errno (_ ("could not read '%s'" ), path );
342349 else
343350 err = write_entry (args , & fake_oid , path_in_archive .buf ,
@@ -493,6 +500,7 @@ static void extra_file_info_clear(void *util, const char *str)
493500{
494501 struct extra_file_info * info = util ;
495502 free (info -> base );
503+ free (info -> content );
496504 free (info );
497505}
498506
@@ -514,14 +522,38 @@ static int add_file_cb(const struct option *opt, const char *arg, int unset)
514522 if (!arg )
515523 return -1 ;
516524
517- path = prefix_filename (args -> prefix , arg );
518- item = string_list_append_nodup (& args -> extra_files , path );
519- item -> util = info = xmalloc (sizeof (* info ));
525+ info = xmalloc (sizeof (* info ));
520526 info -> base = xstrdup_or_null (base );
521- if (stat (path , & info -> stat ))
522- die (_ ("File not found: %s" ), path );
523- if (!S_ISREG (info -> stat .st_mode ))
524- die (_ ("Not a regular file: %s" ), path );
527+
528+ if (strcmp (opt -> long_name , "add-file-with-content" )) {
529+ path = prefix_filename (args -> prefix , arg );
530+ if (stat (path , & info -> stat ))
531+ die (_ ("File not found: %s" ), path );
532+ if (!S_ISREG (info -> stat .st_mode ))
533+ die (_ ("Not a regular file: %s" ), path );
534+ info -> content = NULL ; /* read the file later */
535+ } else {
536+ const char * colon = strchr (arg , ':' );
537+ char * p ;
538+
539+ if (!colon )
540+ die (_ ("missing colon: '%s'" ), arg );
541+
542+ p = xstrndup (arg , colon - arg );
543+ if (!args -> prefix )
544+ path = p ;
545+ else {
546+ path = prefix_filename (args -> prefix , p );
547+ free (p );
548+ }
549+ memset (& info -> stat , 0 , sizeof (info -> stat ));
550+ info -> stat .st_mode = S_IFREG | 0644 ;
551+ info -> content = xstrdup (colon + 1 );
552+ info -> stat .st_size = strlen (info -> content );
553+ }
554+ item = string_list_append_nodup (& args -> extra_files , path );
555+ item -> util = info ;
556+
525557 return 0 ;
526558}
527559
@@ -554,6 +586,9 @@ static int parse_archive_args(int argc, const char **argv,
554586 { OPTION_CALLBACK , 0 , "add-file" , args , N_ ("file" ),
555587 N_ ("add untracked file to archive" ), 0 , add_file_cb ,
556588 (intptr_t )& base },
589+ { OPTION_CALLBACK , 0 , "add-file-with-content" , args ,
590+ N_ ("file" ), N_ ("add untracked file to archive" ), 0 ,
591+ add_file_cb , (intptr_t )& base },
557592 OPT_STRING ('o' , "output" , & output , N_ ("file" ),
558593 N_ ("write the archive to this file" )),
559594 OPT_BOOL (0 , "worktree-attributes" , & worktree_attributes ,
0 commit comments