Skip to content

Commit dce73bd

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 049317d commit dce73bd

File tree

6 files changed

+72
-18
lines changed

6 files changed

+72
-18
lines changed

Diff for: Documentation/git-status.txt

+6-4
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,12 @@ ignored, then the directory is not shown, but all contents are shown.
151151
threshold.
152152
See also linkgit:git-diff[1] `--find-renames`.
153153

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

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

Diff for: builtin/commit.c

+27-9
Original file line numberDiff line numberDiff line change
@@ -165,26 +165,34 @@ static int opt_parse_porcelain(const struct option *opt, const char *arg, int un
165165
}
166166

167167
static int do_serialize = 0;
168+
static char *serialize_path = NULL;
169+
168170
static int do_implicit_deserialize = 0;
169171
static int do_explicit_deserialize = 0;
170172
static char *deserialize_path = NULL;
171173

172174
/*
173-
* --serialize | --serialize=1 | --serialize=v1
175+
* --serialize | --serialize=<path>
176+
*
177+
* Request that we serialize status output rather than or in addition to
178+
* printing in any of the established formats.
179+
*
180+
* Without a path, we write binary serialization data to stdout (and omit
181+
* the normal status output).
174182
*
175-
* Request that we serialize our output rather than printing in
176-
* any of the established formats. Optionally specify serialization
177-
* version.
183+
* With a path, we write binary serialization data to the <path> and then
184+
* write normal status output.
178185
*/
179186
static int opt_parse_serialize(const struct option *opt, const char *arg, int unset)
180187
{
181188
enum wt_status_format *value = (enum wt_status_format *)opt->value;
182189
if (unset || !arg)
183190
*value = STATUS_FORMAT_SERIALIZE_V1;
184-
else if (!strcmp(arg, "v1") || !strcmp(arg, "1"))
185-
*value = STATUS_FORMAT_SERIALIZE_V1;
186-
else
187-
die("unsupported serialize version '%s'", arg);
191+
192+
if (arg) {
193+
free(serialize_path);
194+
serialize_path = xstrdup(arg);
195+
}
188196

189197
if (do_explicit_deserialize)
190198
die("cannot mix --serialize and --deserialize");
@@ -1616,7 +1624,7 @@ struct repository *repo UNUSED)
16161624
N_("version"), N_("machine-readable output"),
16171625
PARSE_OPT_OPTARG, opt_parse_porcelain),
16181626
{ OPTION_CALLBACK, 0, "serialize", &status_format,
1619-
N_("version"), N_("serialize raw status data to stdout"),
1627+
N_("path"), N_("serialize raw status data to path or stdout"),
16201628
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, opt_parse_serialize },
16211629
{ OPTION_CALLBACK, 0, "deserialize", NULL,
16221630
N_("path"), N_("deserialize raw status data from file"),
@@ -1742,6 +1750,16 @@ struct repository *repo UNUSED)
17421750
if (s.relative_paths)
17431751
s.prefix = prefix;
17441752

1753+
if (serialize_path) {
1754+
int fd_serialize = xopen(serialize_path,
1755+
O_WRONLY | O_CREAT | O_TRUNC, 0666);
1756+
if (fd_serialize < 0)
1757+
die_errno(_("could not serialize to '%s'"),
1758+
serialize_path);
1759+
wt_status_serialize_v1(fd_serialize, &s);
1760+
close(fd_serialize);
1761+
}
1762+
17451763
wt_status_print(&s);
17461764
wt_status_collect_free_buffers(&s);
17471765

Diff for: t/t7522-serialized-status.sh

+35
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

Diff for: wt-status-serialize.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ static inline void wt_serialize_v1_ignored(struct wt_status *s UNUSED, 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 UNUSED, 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
size_t k;
186185

Diff for: wt-status.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2628,7 +2628,7 @@ void wt_status_print(struct wt_status *s)
26282628
wt_longstatus_print(s);
26292629
break;
26302630
case STATUS_FORMAT_SERIALIZE_V1:
2631-
wt_status_serialize_v1(s);
2631+
wt_status_serialize_v1(1, s);
26322632
break;
26332633
}
26342634

Diff for: wt-status.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ struct wt_status_serialize_data
224224
* Serialize computed status scan results using "version 1" format
225225
* to the given file.
226226
*/
227-
void wt_status_serialize_v1(struct wt_status *s);
227+
void wt_status_serialize_v1(int fd, struct wt_status *s);
228228

229229
/*
230230
* Deserialize existing status results from the given file and

0 commit comments

Comments
 (0)