Skip to content

Commit 653160a

Browse files
jeffhostetlerdscho
authored andcommitted
status: serialize to path
Teach status serialization to take an optional pathname on the command line to direct that cache data be written there rather than to stdout. When used this way, normal status results will still be written to stdout. When no path is given, only binary serialization data is written to stdout. Usage: git status --serialize[=<path>] Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
1 parent 9fd19ba commit 653160a

File tree

6 files changed

+72
-18
lines changed

6 files changed

+72
-18
lines changed

Documentation/git-status.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,12 @@ ignored, then the directory is not shown, but all contents are shown.
149149
threshold.
150150
See also linkgit:git-diff[1] `--find-renames`.
151151

152-
--serialize[=<version>]::
153-
(EXPERIMENTAL) Serialize raw status results to stdout in a
154-
format suitable for use by `--deserialize`. Valid values for
155-
`<version>` are "1" and "v1".
152+
--serialize[=<path>]::
153+
(EXPERIMENTAL) Serialize raw status results to a file or stdout
154+
in a format suitable for use by `--deserialize`. If a path is
155+
given, serialize data will be written to that path *and* normal
156+
status output will be written to stdout. If path is omitted,
157+
only binary serialization data will be written to stdout.
156158

157159
--deserialize[=<path>]::
158160
(EXPERIMENTAL) Deserialize raw status results from a file or

builtin/commit.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,26 +176,34 @@ static int opt_parse_porcelain(const struct option *opt, const char *arg, int un
176176
}
177177

178178
static int do_serialize = 0;
179+
static char *serialize_path = NULL;
180+
179181
static int do_implicit_deserialize = 0;
180182
static int do_explicit_deserialize = 0;
181183
static char *deserialize_path = NULL;
182184

183185
/*
184-
* --serialize | --serialize=1 | --serialize=v1
186+
* --serialize | --serialize=<path>
187+
*
188+
* Request that we serialize status output rather than or in addition to
189+
* printing in any of the established formats.
190+
*
191+
* Without a path, we write binary serialization data to stdout (and omit
192+
* the normal status output).
185193
*
186-
* Request that we serialize our output rather than printing in
187-
* any of the established formats. Optionally specify serialization
188-
* version.
194+
* With a path, we write binary serialization data to the <path> and then
195+
* write normal status output.
189196
*/
190197
static int opt_parse_serialize(const struct option *opt, const char *arg, int unset)
191198
{
192199
enum wt_status_format *value = (enum wt_status_format *)opt->value;
193200
if (unset || !arg)
194201
*value = STATUS_FORMAT_SERIALIZE_V1;
195-
else if (!strcmp(arg, "v1") || !strcmp(arg, "1"))
196-
*value = STATUS_FORMAT_SERIALIZE_V1;
197-
else
198-
die("unsupported serialize version '%s'", arg);
202+
203+
if (arg) {
204+
free(serialize_path);
205+
serialize_path = xstrdup(arg);
206+
}
199207

200208
if (do_explicit_deserialize)
201209
die("cannot mix --serialize and --deserialize");
@@ -1599,7 +1607,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
15991607
N_("version"), N_("machine-readable output"),
16001608
PARSE_OPT_OPTARG, opt_parse_porcelain),
16011609
{ OPTION_CALLBACK, 0, "serialize", &status_format,
1602-
N_("version"), N_("serialize raw status data to stdout"),
1610+
N_("path"), N_("serialize raw status data to path or stdout"),
16031611
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_serialize },
16041612
{ OPTION_CALLBACK, 0, "deserialize", NULL,
16051613
N_("path"), N_("deserialize raw status data from file"),
@@ -1725,6 +1733,16 @@ int cmd_status(int argc, const char **argv, const char *prefix)
17251733
if (s.relative_paths)
17261734
s.prefix = prefix;
17271735

1736+
if (serialize_path) {
1737+
int fd_serialize = xopen(serialize_path,
1738+
O_WRONLY | O_CREAT | O_TRUNC, 0666);
1739+
if (fd_serialize < 0)
1740+
die_errno(_("could not serialize to '%s'"),
1741+
serialize_path);
1742+
wt_status_serialize_v1(fd_serialize, &s);
1743+
close(fd_serialize);
1744+
}
1745+
17281746
wt_status_print(&s);
17291747
wt_status_collect_free_buffers(&s);
17301748

t/t7522-serialized-status.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,39 @@ test_expect_success 'verify no-ahead-behind and serialized status integration' '
170170
test_cmp expect output
171171
'
172172

173+
test_expect_success 'verify new --serialize=path mode' '
174+
#test_when_finished "rm serialized_status.dat expect new_change.txt output.1 output.2" &&
175+
cat >expect <<-\EOF &&
176+
? expect
177+
? output.1
178+
? untracked/
179+
? untracked_1.txt
180+
EOF
181+
182+
git checkout -b serialize_path_branch main --track >/dev/null &&
183+
touch alt_branch_changes.txt &&
184+
git add alt_branch_changes.txt &&
185+
test_tick &&
186+
git commit -m"New commit on serialize_path_branch" &&
187+
188+
git status --porcelain=v2 --serialize=serialized_status.dat >output.1 &&
189+
touch new_change.txt &&
190+
191+
git status --porcelain=v2 --deserialize=serialized_status.dat >output.2 &&
192+
test_cmp expect output.1 &&
193+
test_cmp expect output.2
194+
'
195+
196+
test_expect_success 'renames' '
197+
git init -b main rename_test &&
198+
echo OLDNAME >rename_test/OLDNAME &&
199+
git -C rename_test add OLDNAME &&
200+
git -C rename_test commit -m OLDNAME &&
201+
git -C rename_test mv OLDNAME NEWNAME &&
202+
git -C rename_test status --serialize=renamed.dat >output.1 &&
203+
echo DIRT >rename_test/DIRT &&
204+
git -C rename_test status --deserialize=renamed.dat >output.2 &&
205+
test_cmp output.1 output.2
206+
'
207+
173208
test_done

wt-status-serialize.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static inline void wt_serialize_v1_ignored(struct wt_status *s, int fd,
169169
}
170170

171171
/*
172-
* Serialize the list of changes to stdout. The goal of this
172+
* Serialize the list of changes to the given file. The goal of this
173173
* is to just serialize the key fields in wt_status so that a
174174
* later command can rebuilt it and do the printing.
175175
*
@@ -178,9 +178,8 @@ static inline void wt_serialize_v1_ignored(struct wt_status *s, int fd,
178178
* is relatively quick for the status consumer to compute
179179
* as necessary.
180180
*/
181-
void wt_status_serialize_v1(struct wt_status *s)
181+
void wt_status_serialize_v1(int fd, struct wt_status *s)
182182
{
183-
int fd = 1; /* we always write to stdout */
184183
struct string_list_item *iter;
185184
int k;
186185

wt-status.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2573,7 +2573,7 @@ void wt_status_print(struct wt_status *s)
25732573
wt_longstatus_print(s);
25742574
break;
25752575
case STATUS_FORMAT_SERIALIZE_V1:
2576-
wt_status_serialize_v1(s);
2576+
wt_status_serialize_v1(1, s);
25772577
break;
25782578
}
25792579

wt-status.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ struct wt_status_serialize_data
221221
* Serialize computed status scan results using "version 1" format
222222
* to the given file.
223223
*/
224-
void wt_status_serialize_v1(struct wt_status *s);
224+
void wt_status_serialize_v1(int fd, struct wt_status *s);
225225

226226
/*
227227
* Deserialize existing status results from the given file and

0 commit comments

Comments
 (0)