Skip to content

Commit a178ba6

Browse files
dschomjcheetham
authored andcommitted
Merge core VFS features
These were done in private, before microsoft/git. Signed-off-by: Derrick Stolee <[email protected]>
2 parents 95a07de + 28d0788 commit a178ba6

26 files changed

+862
-12
lines changed

Documentation/config/core.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,48 @@ core.multiPackIndex::
743743
single index. See linkgit:git-multi-pack-index[1] for more
744744
information. Defaults to true.
745745

746+
core.gvfs::
747+
Enable the features needed for GVFS. This value can be set to true
748+
to indicate all features should be turned on or the bit values listed
749+
below can be used to turn on specific features.
750+
+
751+
--
752+
GVFS_SKIP_SHA_ON_INDEX::
753+
Bit value 1
754+
Disables the calculation of the sha when writing the index
755+
GVFS_MISSING_OK::
756+
Bit value 4
757+
Normally git write-tree ensures that the objects referenced by the
758+
directory exist in the object database. This option disables this check.
759+
GVFS_NO_DELETE_OUTSIDE_SPARSECHECKOUT::
760+
Bit value 8
761+
When marking entries to remove from the index and the working
762+
directory this option will take into account what the
763+
skip-worktree bit was set to so that if the entry has the
764+
skip-worktree bit set it will not be removed from the working
765+
directory. This will allow virtualized working directories to
766+
detect the change to HEAD and use the new commit tree to show
767+
the files that are in the working directory.
768+
GVFS_FETCH_SKIP_REACHABILITY_AND_UPLOADPACK::
769+
Bit value 16
770+
While performing a fetch with a virtual file system we know
771+
that there will be missing objects and we don't want to download
772+
them just because of the reachability of the commits. We also
773+
don't want to download a pack file with commits, trees, and blobs
774+
since these will be downloaded on demand. This flag will skip the
775+
checks on the reachability of objects during a fetch as well as
776+
the upload pack so that extraneous objects don't get downloaded.
777+
GVFS_BLOCK_FILTERS_AND_EOL_CONVERSIONS::
778+
Bit value 64
779+
With a virtual file system we only know the file size before any
780+
CRLF or smudge/clean filters processing is done on the client.
781+
To prevent file corruption due to truncation or expansion with
782+
garbage at the end, these filters must not run when the file
783+
is first accessed and brought down to the client. Git.exe can't
784+
currently tell the first access vs subsequent accesses so this
785+
flag just blocks them from occurring at all.
786+
--
787+
746788
core.sparseCheckout::
747789
Enable "sparse checkout" feature. See linkgit:git-sparse-checkout[1]
748790
for more information.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
Read Object Process
2+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
3+
4+
The read-object process enables Git to read all missing blobs with a
5+
single process invocation for the entire life of a single Git command.
6+
This is achieved by using a packet format (pkt-line, see technical/
7+
protocol-common.txt) based protocol over standard input and standard
8+
output as follows. All packets, except for the "*CONTENT" packets and
9+
the "0000" flush packet, are considered text and therefore are
10+
terminated by a LF.
11+
12+
Git starts the process when it encounters the first missing object that
13+
needs to be retrieved. After the process is started, Git sends a welcome
14+
message ("git-read-object-client"), a list of supported protocol version
15+
numbers, and a flush packet. Git expects to read a welcome response
16+
message ("git-read-object-server"), exactly one protocol version number
17+
from the previously sent list, and a flush packet. All further
18+
communication will be based on the selected version.
19+
20+
The remaining protocol description below documents "version=1". Please
21+
note that "version=42" in the example below does not exist and is only
22+
there to illustrate how the protocol would look with more than one
23+
version.
24+
25+
After the version negotiation Git sends a list of all capabilities that
26+
it supports and a flush packet. Git expects to read a list of desired
27+
capabilities, which must be a subset of the supported capabilities list,
28+
and a flush packet as response:
29+
------------------------
30+
packet: git> git-read-object-client
31+
packet: git> version=1
32+
packet: git> version=42
33+
packet: git> 0000
34+
packet: git< git-read-object-server
35+
packet: git< version=1
36+
packet: git< 0000
37+
packet: git> capability=get
38+
packet: git> capability=have
39+
packet: git> capability=put
40+
packet: git> capability=not-yet-invented
41+
packet: git> 0000
42+
packet: git< capability=get
43+
packet: git< 0000
44+
------------------------
45+
The only supported capability in version 1 is "get".
46+
47+
Afterwards Git sends a list of "key=value" pairs terminated with a flush
48+
packet. The list will contain at least the command (based on the
49+
supported capabilities) and the sha1 of the object to retrieve. Please
50+
note, that the process must not send any response before it received the
51+
final flush packet.
52+
53+
When the process receives the "get" command, it should make the requested
54+
object available in the git object store and then return success. Git will
55+
then check the object store again and this time find it and proceed.
56+
------------------------
57+
packet: git> command=get
58+
packet: git> sha1=0a214a649e1b3d5011e14a3dc227753f2bd2be05
59+
packet: git> 0000
60+
------------------------
61+
62+
The process is expected to respond with a list of "key=value" pairs
63+
terminated with a flush packet. If the process does not experience
64+
problems then the list must contain a "success" status.
65+
------------------------
66+
packet: git< status=success
67+
packet: git< 0000
68+
------------------------
69+
70+
In case the process cannot or does not want to process the content, it
71+
is expected to respond with an "error" status.
72+
------------------------
73+
packet: git< status=error
74+
packet: git< 0000
75+
------------------------
76+
77+
In case the process cannot or does not want to process the content as
78+
well as any future content for the lifetime of the Git process, then it
79+
is expected to respond with an "abort" status at any point in the
80+
protocol.
81+
------------------------
82+
packet: git< status=abort
83+
packet: git< 0000
84+
------------------------
85+
86+
Git neither stops nor restarts the process in case the "error"/"abort"
87+
status is set.
88+
89+
If the process dies during the communication or does not adhere to the
90+
protocol then Git will stop the process and restart it with the next
91+
object that needs to be processed.
92+
93+
After the read-object process has processed an object it is expected to
94+
wait for the next "key=value" list containing a command. Git will close
95+
the command pipe on exit. The process is expected to detect EOF and exit
96+
gracefully on its own. Git will wait until the process has stopped.
97+
98+
A long running read-object process demo implementation can be found in
99+
`contrib/long-running-read-object/example.pl` located in the Git core
100+
repository. If you develop your own long running process then the
101+
`GIT_TRACE_PACKET` environment variables can be very helpful for
102+
debugging (see linkgit:git[1]).

GIT-VERSION-GEN

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
GVF=GIT-VERSION-FILE
44
DEF_VER=v2.47.1
55

6+
# Identify microsoft/git via a distinct version suffix
7+
DEF_VER=$DEF_VER.vfs.0.0
8+
69
LF='
710
'
811

@@ -12,10 +15,15 @@ if test -f version
1215
then
1316
VN=$(cat version) || VN="$DEF_VER"
1417
elif { test -d "${GIT_DIR:-.git}" || test -f .git; } &&
15-
VN=$(git describe --match "v[0-9]*" HEAD 2>/dev/null) &&
18+
VN=$(git describe --match "v[0-9]*vfs*" HEAD 2>/dev/null) &&
1619
case "$VN" in
1720
*$LF*) (exit 1) ;;
1821
v[0-9]*)
22+
if test "${VN%%.vfs.*}" != "${DEF_VER%%.vfs.*}"
23+
then
24+
echo "Found version $VN, which is not based on $DEF_VER" >&2
25+
exit 1
26+
fi
1927
git update-index -q --refresh
2028
test -z "$(git diff-index --name-only HEAD --)" ||
2129
VN="$VN-dirty" ;;

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,7 @@ LIB_OBJS += git-zlib.o
10421042
LIB_OBJS += gpg-interface.o
10431043
LIB_OBJS += graph.o
10441044
LIB_OBJS += grep.o
1045+
LIB_OBJS += gvfs.o
10451046
LIB_OBJS += hash-lookup.o
10461047
LIB_OBJS += hashmap.o
10471048
LIB_OBJS += help.o

cache-tree.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "git-compat-util.h"
44
#include "gettext.h"
55
#include "hex.h"
6+
#include "gvfs.h"
67
#include "lockfile.h"
78
#include "tree.h"
89
#include "tree-walk.h"
@@ -260,7 +261,8 @@ static int update_one(struct cache_tree *it,
260261
int flags)
261262
{
262263
struct strbuf buffer;
263-
int missing_ok = flags & WRITE_TREE_MISSING_OK;
264+
int missing_ok = gvfs_config_is_set(GVFS_MISSING_OK) ?
265+
WRITE_TREE_MISSING_OK : (flags & WRITE_TREE_MISSING_OK);
264266
int dryrun = flags & WRITE_TREE_DRY_RUN;
265267
int repair = flags & WRITE_TREE_REPAIR;
266268
int to_invalidate = 0;

commit.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#define USE_THE_REPOSITORY_VARIABLE
22

33
#include "git-compat-util.h"
4+
#include "gvfs.h"
45
#include "tag.h"
56
#include "commit.h"
67
#include "commit-graph.h"
@@ -556,13 +557,17 @@ int repo_parse_commit_internal(struct repository *r,
556557
.sizep = &size,
557558
.contentp = &buffer,
558559
};
560+
int ret;
559561
/*
560562
* Git does not support partial clones that exclude commits, so set
561563
* OBJECT_INFO_SKIP_FETCH_OBJECT to fail fast when an object is missing.
562564
*/
563565
int flags = OBJECT_INFO_LOOKUP_REPLACE | OBJECT_INFO_SKIP_FETCH_OBJECT |
564-
OBJECT_INFO_DIE_IF_CORRUPT;
565-
int ret;
566+
OBJECT_INFO_DIE_IF_CORRUPT;
567+
568+
/* But the GVFS Protocol _does_ support missing commits! */
569+
if (gvfs_config_is_set(GVFS_MISSING_OK))
570+
flags ^= OBJECT_INFO_SKIP_FETCH_OBJECT;
566571

567572
if (!item)
568573
return -1;

config.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "abspath.h"
1313
#include "advice.h"
1414
#include "date.h"
15+
#include "gvfs.h"
1516
#include "branch.h"
1617
#include "config.h"
1718
#include "parse.h"
@@ -1642,6 +1643,11 @@ int git_default_core_config(const char *var, const char *value,
16421643
return 0;
16431644
}
16441645

1646+
if (!strcmp(var, "core.gvfs")) {
1647+
gvfs_load_config_value(value);
1648+
return 0;
1649+
}
1650+
16451651
if (!strcmp(var, "core.sparsecheckout")) {
16461652
core_apply_sparse_checkout = git_config_bool(var, value);
16471653
return 0;
@@ -1672,6 +1678,11 @@ int git_default_core_config(const char *var, const char *value,
16721678
return 0;
16731679
}
16741680

1681+
if (!strcmp(var, "core.virtualizeobjects")) {
1682+
core_virtualize_objects = git_config_bool(var, value);
1683+
return 0;
1684+
}
1685+
16751686
/* Add other config variables here and to Documentation/config.txt. */
16761687
return platform_core_config(var, value, ctx, cb);
16771688
}

connected.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#define USE_THE_REPOSITORY_VARIABLE
22

33
#include "git-compat-util.h"
4+
#include "environment.h"
45
#include "gettext.h"
56
#include "hex.h"
7+
#include "gvfs.h"
68
#include "object-store-ll.h"
79
#include "run-command.h"
810
#include "sigchain.h"
@@ -34,6 +36,26 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
3436
struct transport *transport;
3537
size_t base_len;
3638

39+
/*
40+
* Running a virtual file system there will be objects that are
41+
* missing locally and we don't want to download a bunch of
42+
* commits, trees, and blobs just to make sure everything is
43+
* reachable locally so this option will skip reachablility
44+
* checks below that use rev-list. This will stop the check
45+
* before uploadpack runs to determine if there is anything to
46+
* fetch. Returning zero for the first check will also prevent the
47+
* uploadpack from happening. It will also skip the check after
48+
* the fetch is finished to make sure all the objects where
49+
* downloaded in the pack file. This will allow the fetch to
50+
* run and get all the latest tip commit ids for all the branches
51+
* in the fetch but not pull down commits, trees, or blobs via
52+
* upload pack.
53+
*/
54+
if (gvfs_config_is_set(GVFS_FETCH_SKIP_REACHABILITY_AND_UPLOADPACK))
55+
return 0;
56+
if (core_virtualize_objects)
57+
return 0;
58+
3759
if (!opt)
3860
opt = &defaults;
3961
transport = opt->transport;

0 commit comments

Comments
 (0)