Skip to content

Commit 487fe1f

Browse files
committed
Merge branch 'ls/filter-process-delayed' into jt/subprocess-handshake
* ls/filter-process-delayed: convert: add "status=delayed" to filter process protocol convert: refactor capabilities negotiation convert: move multiple file filter error handling to separate function convert: put the flags field before the flag itself for consistent style t0021: write "OUT <size>" only on success t0021: make debug log file name configurable t0021: keep filter log files on comparison
2 parents 5800c63 + 2841e8f commit 487fe1f

File tree

9 files changed

+668
-161
lines changed

9 files changed

+668
-161
lines changed

Documentation/gitattributes.txt

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,8 @@ packet: git< capability=clean
425425
packet: git< capability=smudge
426426
packet: git< 0000
427427
------------------------
428-
Supported filter capabilities in version 2 are "clean" and
429-
"smudge".
428+
Supported filter capabilities in version 2 are "clean", "smudge",
429+
and "delay".
430430

431431
Afterwards Git sends a list of "key=value" pairs terminated with
432432
a flush packet. The list will contain at least the filter command
@@ -512,12 +512,73 @@ the protocol then Git will stop the filter process and restart it
512512
with the next file that needs to be processed. Depending on the
513513
`filter.<driver>.required` flag Git will interpret that as error.
514514

515-
After the filter has processed a blob it is expected to wait for
516-
the next "key=value" list containing a command. Git will close
515+
After the filter has processed a command it is expected to wait for
516+
a "key=value" list containing the next command. Git will close
517517
the command pipe on exit. The filter is expected to detect EOF
518518
and exit gracefully on its own. Git will wait until the filter
519519
process has stopped.
520520

521+
Delay
522+
^^^^^
523+
524+
If the filter supports the "delay" capability, then Git can send the
525+
flag "can-delay" after the filter command and pathname. This flag
526+
denotes that the filter can delay filtering the current blob (e.g. to
527+
compensate network latencies) by responding with no content but with
528+
the status "delayed" and a flush packet.
529+
------------------------
530+
packet: git> command=smudge
531+
packet: git> pathname=path/testfile.dat
532+
packet: git> can-delay=1
533+
packet: git> 0000
534+
packet: git> CONTENT
535+
packet: git> 0000
536+
packet: git< status=delayed
537+
packet: git< 0000
538+
------------------------
539+
540+
If the filter supports the "delay" capability then it must support the
541+
"list_available_blobs" command. If Git sends this command, then the
542+
filter is expected to return a list of pathnames representing blobs
543+
that have been delayed earlier and are now available.
544+
The list must be terminated with a flush packet followed
545+
by a "success" status that is also terminated with a flush packet. If
546+
no blobs for the delayed paths are available, yet, then the filter is
547+
expected to block the response until at least one blob becomes
548+
available. The filter can tell Git that it has no more delayed blobs
549+
by sending an empty list. As soon as the filter responds with an empty
550+
list, Git stops asking. All blobs that Git has not received at this
551+
point are considered missing and will result in an error.
552+
553+
------------------------
554+
packet: git> command=list_available_blobs
555+
packet: git> 0000
556+
packet: git< pathname=path/testfile.dat
557+
packet: git< pathname=path/otherfile.dat
558+
packet: git< 0000
559+
packet: git< status=success
560+
packet: git< 0000
561+
------------------------
562+
563+
After Git received the pathnames, it will request the corresponding
564+
blobs again. These requests contain a pathname and an empty content
565+
section. The filter is expected to respond with the smudged content
566+
in the usual way as explained above.
567+
------------------------
568+
packet: git> command=smudge
569+
packet: git> pathname=path/testfile.dat
570+
packet: git> 0000
571+
packet: git> 0000 # empty content!
572+
packet: git< status=success
573+
packet: git< 0000
574+
packet: git< SMUDGED_CONTENT
575+
packet: git< 0000
576+
packet: git< 0000 # empty list, keep "status=success" unchanged!
577+
------------------------
578+
579+
Example
580+
^^^^^^^
581+
521582
A long running filter demo implementation can be found in
522583
`contrib/long-running-filter/example.pl` located in the Git
523584
core repository. If you develop your own long running filter

builtin/checkout.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ static int checkout_paths(const struct checkout_opts *opts,
358358
state.force = 1;
359359
state.refresh_cache = 1;
360360
state.istate = &the_index;
361+
362+
enable_delayed_checkout(&state);
361363
for (pos = 0; pos < active_nr; pos++) {
362364
struct cache_entry *ce = active_cache[pos];
363365
if (ce->ce_flags & CE_MATCHED) {
@@ -372,6 +374,7 @@ static int checkout_paths(const struct checkout_opts *opts,
372374
pos = skip_same_name(ce, pos) - 1;
373375
}
374376
}
377+
errs |= finish_delayed_checkout(&state);
375378

376379
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
377380
die(_("unable to write new index file"));

cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,7 @@ struct checkout {
14921492
struct index_state *istate;
14931493
const char *base_dir;
14941494
int base_dir_len;
1495+
struct delayed_checkout *delayed_checkout;
14951496
unsigned force:1,
14961497
quiet:1,
14971498
not_new:1,
@@ -1501,6 +1502,8 @@ struct checkout {
15011502

15021503
#define TEMPORARY_FILENAME_LENGTH 25
15031504
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
1505+
extern void enable_delayed_checkout(struct checkout *state);
1506+
extern int finish_delayed_checkout(struct checkout *state);
15041507

15051508
struct cache_def {
15061509
struct strbuf path;

0 commit comments

Comments
 (0)