@@ -263,6 +263,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,
263
263
struct extra_file_info {
264
264
char * base ;
265
265
struct stat stat ;
266
+ void * content ;
266
267
};
267
268
268
269
int write_archive_entries (struct archiver_args * args ,
@@ -331,19 +332,27 @@ int write_archive_entries(struct archiver_args *args,
331
332
332
333
put_be64 (fake_oid .hash , i + 1 );
333
334
334
- strbuf_reset (& path_in_archive );
335
- if (info -> base )
336
- strbuf_addstr (& path_in_archive , info -> base );
337
- strbuf_addstr (& path_in_archive , basename (path ));
338
-
339
- strbuf_reset (& content );
340
- if (strbuf_read_file (& content , path , info -> stat .st_size ) < 0 )
341
- err = error_errno (_ ("cannot read '%s'" ), path );
342
- else
343
- err = write_entry (args , & fake_oid , path_in_archive .buf ,
344
- path_in_archive .len ,
335
+ if (!info -> content ) {
336
+ strbuf_reset (& path_in_archive );
337
+ if (info -> base )
338
+ strbuf_addstr (& path_in_archive , info -> base );
339
+ strbuf_addstr (& path_in_archive , basename (path ));
340
+
341
+ strbuf_reset (& content );
342
+ if (strbuf_read_file (& content , path , info -> stat .st_size ) < 0 )
343
+ err = error_errno (_ ("cannot read '%s'" ), path );
344
+ else
345
+ err = write_entry (args , & fake_oid , path_in_archive .buf ,
346
+ path_in_archive .len ,
347
+ canon_mode (info -> stat .st_mode ),
348
+ content .buf , content .len );
349
+ } else {
350
+ err = write_entry (args , & fake_oid ,
351
+ path , strlen (path ),
345
352
canon_mode (info -> stat .st_mode ),
346
- content .buf , content .len );
353
+ info -> content , info -> stat .st_size );
354
+ }
355
+
347
356
if (err )
348
357
break ;
349
358
}
@@ -493,6 +502,7 @@ static void extra_file_info_clear(void *util, const char *str)
493
502
{
494
503
struct extra_file_info * info = util ;
495
504
free (info -> base );
505
+ free (info -> content );
496
506
free (info );
497
507
}
498
508
@@ -514,14 +524,40 @@ static int add_file_cb(const struct option *opt, const char *arg, int unset)
514
524
if (!arg )
515
525
return -1 ;
516
526
517
- path = prefix_filename (args -> prefix , arg );
518
- item = string_list_append_nodup (& args -> extra_files , path );
519
- item -> util = info = xmalloc (sizeof (* info ));
527
+ info = xmalloc (sizeof (* info ));
520
528
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 );
529
+
530
+ if (!strcmp (opt -> long_name , "add-file" )) {
531
+ path = prefix_filename (args -> prefix , arg );
532
+ if (stat (path , & info -> stat ))
533
+ die (_ ("File not found: %s" ), path );
534
+ if (!S_ISREG (info -> stat .st_mode ))
535
+ die (_ ("Not a regular file: %s" ), path );
536
+ info -> content = NULL ; /* read the file later */
537
+ } else if (!strcmp (opt -> long_name , "add-virtual-file" )) {
538
+ const char * colon = strchr (arg , ':' );
539
+ char * p ;
540
+
541
+ if (!colon )
542
+ die (_ ("missing colon: '%s'" ), arg );
543
+
544
+ p = xstrndup (arg , colon - arg );
545
+ if (!args -> prefix )
546
+ path = p ;
547
+ else {
548
+ path = prefix_filename (args -> prefix , p );
549
+ free (p );
550
+ }
551
+ memset (& info -> stat , 0 , sizeof (info -> stat ));
552
+ info -> stat .st_mode = S_IFREG | 0644 ;
553
+ info -> content = xstrdup (colon + 1 );
554
+ info -> stat .st_size = strlen (info -> content );
555
+ } else {
556
+ BUG ("add_file_cb() called for %s" , opt -> long_name );
557
+ }
558
+ item = string_list_append_nodup (& args -> extra_files , path );
559
+ item -> util = info ;
560
+
525
561
return 0 ;
526
562
}
527
563
@@ -554,6 +590,9 @@ static int parse_archive_args(int argc, const char **argv,
554
590
{ OPTION_CALLBACK , 0 , "add-file" , args , N_ ("file" ),
555
591
N_ ("add untracked file to archive" ), 0 , add_file_cb ,
556
592
(intptr_t )& base },
593
+ { OPTION_CALLBACK , 0 , "add-virtual-file" , args ,
594
+ N_ ("path:content" ), N_ ("add untracked file to archive" ), 0 ,
595
+ add_file_cb , (intptr_t )& base },
557
596
OPT_STRING ('o' , "output" , & output , N_ ("file" ),
558
597
N_ ("write the archive to this file" )),
559
598
OPT_BOOL (0 , "worktree-attributes" , & worktree_attributes ,
0 commit comments