mirror of
https://github.com/git/git.git
synced 2026-03-28 17:40:11 +01:00
write-index: check and warn when worktree crosses a filesystem boundary
As we are stopping the discovery for the repository directory at
filesystem boundaries by default, you might find yourself in a
situation like this:
(1) You have a tarball of some sort; you extract it $there;
$ mkdir $there && cd $there
$ tar xf /var/tmp/tarball.tar
(2) You notice that the filesystem lacks enough free space, and
move some part (say "images/") to a separate filesystem, and
bind-mount;
$ mv images $another/. && rm -fr images && mkdir images
$ mount --bind $another/images images
(3) You add everything to start the project;
$ git init && git add .
Up to this point it would work just fine, as you are at the
top of the working tree and there is no need for repository
discovery.
(4) Go down to a subdirectory and start futzing;
$ cd images && gimp naughty.jpg && git add -u
This will break as the repository discovery will not go up
outside of the "images" directory.
Help users by making "git add" notice at the step (3) above that
the working tree is spread across multiple filesystems and warn.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
14
read-cache.c
14
read-cache.c
@@ -1550,6 +1550,8 @@ int write_index(struct index_state *istate, int newfd)
|
||||
struct cache_entry **cache = istate->cache;
|
||||
int entries = istate->cache_nr;
|
||||
struct stat st;
|
||||
int first_valid_ent = -1;
|
||||
int more_than_one_dev;
|
||||
|
||||
for (i = removed = extended = 0; i < entries; i++) {
|
||||
if (cache[i]->ce_flags & CE_REMOVE)
|
||||
@@ -1572,6 +1574,7 @@ int write_index(struct index_state *istate, int newfd)
|
||||
if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
|
||||
return -1;
|
||||
|
||||
more_than_one_dev = 0;
|
||||
for (i = 0; i < entries; i++) {
|
||||
struct cache_entry *ce = cache[i];
|
||||
if (ce->ce_flags & CE_REMOVE)
|
||||
@@ -1580,8 +1583,19 @@ int write_index(struct index_state *istate, int newfd)
|
||||
ce_smudge_racily_clean_entry(ce);
|
||||
if (ce_write_entry(&c, newfd, ce) < 0)
|
||||
return -1;
|
||||
if (ce_uptodate(ce)) {
|
||||
if (first_valid_ent < 0)
|
||||
first_valid_ent = i;
|
||||
else if (ce->ce_dev != cache[first_valid_ent]->ce_dev)
|
||||
more_than_one_dev = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (more_than_one_dev &&
|
||||
!git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0))
|
||||
warning("working tree spans across filesystems but "
|
||||
"GIT_DISCOVERY_ACROSS_FILESYSTEM is not set.");
|
||||
|
||||
/* Write extension data here */
|
||||
if (istate->cache_tree) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
|
||||
Reference in New Issue
Block a user