mirror of
https://github.com/git/git.git
synced 2024-11-05 00:37:55 +01:00
4c324c0050
upload-pack spawns two processes, rev-list and pack-objects, and carefully monitors their status so that it can report failure to the remote end. This change removes the complicated procedures on the grounds of the following observations: - If everything is OK, rev-list closes its output pipe end, upon which pack-objects (which reads from the pipe) sees EOF and terminates itself, closing its output (and error) pipes. upload-pack reads from both until it sees EOF in both. It collects the exit codes of the child processes (which indicate success) and terminates successfully. - If rev-list sees an error, it closes its output and terminates with failure. pack-objects sees EOF in its input and terminates successfully. Again upload-pack reads its inputs until EOF. When it now collects the exit codes of its child processes, it notices the failure of rev-list and signals failure to the remote end. - If pack-objects sees an error, it terminates with failure. Since this breaks the pipe to rev-list, rev-list is killed with SIGPIPE. upload-pack reads its input until EOF, then collects the exit codes of the child processes, notices their failures, and signals failure to the remote end. - If upload-pack itself dies unexpectedly, pack-objects is killed with SIGPIPE, and subsequently also rev-list. The upshot of this is that precise monitoring of child processes is not required because both terminate if either one of them dies unexpectedly. This allows us to use finish_command() and finish_async() instead of an explicit waitpid(2) call. The change is smaller than it looks because most of it only reduces the indentation of a large part of the inner loop. Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
75 lines
1.3 KiB
Bash
Executable file
75 lines
1.3 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='errors in upload-pack'
|
|
|
|
. ./test-lib.sh
|
|
|
|
D=`pwd`
|
|
|
|
corrupt_repo () {
|
|
object_sha1=$(git rev-parse "$1") &&
|
|
ob=$(expr "$object_sha1" : "\(..\)") &&
|
|
ject=$(expr "$object_sha1" : "..\(..*\)") &&
|
|
rm -f ".git/objects/$ob/$ject"
|
|
}
|
|
|
|
test_expect_success 'setup and corrupt repository' '
|
|
|
|
echo file >file &&
|
|
git add file &&
|
|
git rev-parse :file &&
|
|
git commit -a -m original &&
|
|
test_tick &&
|
|
echo changed >file &&
|
|
git commit -a -m changed &&
|
|
corrupt_repo HEAD:file
|
|
|
|
'
|
|
|
|
test_expect_failure 'fsck fails' '
|
|
|
|
git fsck
|
|
'
|
|
|
|
test_expect_success 'upload-pack fails due to error in pack-objects' '
|
|
|
|
! echo "0032want $(git rev-parse HEAD)
|
|
00000009done
|
|
0000" | git-upload-pack . > /dev/null 2> output.err &&
|
|
grep "pack-objects died" output.err
|
|
'
|
|
|
|
test_expect_success 'corrupt repo differently' '
|
|
|
|
git hash-object -w file &&
|
|
corrupt_repo HEAD^^{tree}
|
|
|
|
'
|
|
|
|
test_expect_failure 'fsck fails' '
|
|
|
|
git fsck
|
|
'
|
|
test_expect_success 'upload-pack fails due to error in rev-list' '
|
|
|
|
! echo "0032want $(git rev-parse HEAD)
|
|
00000009done
|
|
0000" | git-upload-pack . > /dev/null 2> output.err &&
|
|
grep "waitpid (async) failed" output.err
|
|
'
|
|
|
|
test_expect_success 'create empty repository' '
|
|
|
|
mkdir foo &&
|
|
cd foo &&
|
|
git init
|
|
|
|
'
|
|
|
|
test_expect_failure 'fetch fails' '
|
|
|
|
git fetch .. master
|
|
|
|
'
|
|
|
|
test_done
|