diff options
author | Mazo, Andrey <amazo@checkvideo.com> | 2019-04-01 18:02:17 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-04-02 11:25:41 +0900 |
commit | 2dda741279ba3c56340f3bd88745604bb5a394a6 (patch) | |
tree | 2a1dfddc9d4d4c3e3358379f8e4943dd6430fa66 /git-p4.py | |
parent | 041f5ea1cf987a4068ef5f39ba0a09be85952064 (diff) | |
download | git-2dda741279ba3c56340f3bd88745604bb5a394a6.tar.gz |
git-p4: detect/prevent infinite loop in gitCommitByP4Change()
Under certain circumstances, gitCommitByP4Change() can enter an infinite
loop resulting in `git p4 sync` hanging forever.
The problem is that
`git rev-list --bisect <latest> ^<earliest>` can return `<latest>`,
which would result in reinspecting <latest> and potentially an infinite loop.
This can happen when importing just a subset of P4 repository
and/or with explicit "--changesfile" option.
A real-life example:
"""
looking in ref refs/remotes/p4/mybranch for change 26894 using bisect...
Reading pipe: git rev-parse refs/remotes/p4/mybranch
trying: earliest latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git cat-file commit 147f5d3292af2e1cc4a56a7b96db845144c68486
current change 25339
trying: earliest ^147f5d3292af2e1cc4a56a7b96db845144c68486 latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1 ^147f5d3292af2e1cc4a56a7b96db845144c68486
Reading pipe: git cat-file commit 51db83df9d588010d0bd995641c85aa0408a5bb9
current change 25420
trying: earliest ^51db83df9d588010d0bd995641c85aa0408a5bb9 latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1 ^51db83df9d588010d0bd995641c85aa0408a5bb9
Reading pipe: git cat-file commit e8f83909ceb570f5a7e48c2853f3c5d8207cea52
current change 25448
trying: earliest ^e8f83909ceb570f5a7e48c2853f3c5d8207cea52 latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1 ^e8f83909ceb570f5a7e48c2853f3c5d8207cea52
Reading pipe: git cat-file commit 09a48eb7acd594dce52e06681be9c366e1844d66
current change 25521
trying: earliest ^09a48eb7acd594dce52e06681be9c366e1844d66 latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1 ^09a48eb7acd594dce52e06681be9c366e1844d66
Reading pipe: git cat-file commit 4daff81c520a82678e1ef347f2b5e97258101ae1
current change 26907
trying: earliest ^09a48eb7acd594dce52e06681be9c366e1844d66 latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1 ^09a48eb7acd594dce52e06681be9c366e1844d66
Reading pipe: git cat-file commit 4daff81c520a82678e1ef347f2b5e97258101ae1
current change 26907
trying: earliest ^09a48eb7acd594dce52e06681be9c366e1844d66 latest 4daff81c520a82678e1ef347f2b5e97258101ae1
Reading pipe: git rev-list --bisect 4daff81c520a82678e1ef347f2b5e97258101ae1 ^09a48eb7acd594dce52e06681be9c366e1844d66
Reading pipe: git cat-file commit 4daff81c520a82678e1ef347f2b5e97258101ae1
current change 26907
...
"""
The fix is two-fold:
* detect an infinite loop and die right away
instead of looping forever;
* make sure, `git rev-list --bisect` can't return "latestCommit" again
by excluding it from the rev-list range explicitly.
Signed-off-by: Andrey Mazo <amazo@checkvideo.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git-p4.py')
-rwxr-xr-x | git-p4.py | 4 |
1 files changed, 3 insertions, 1 deletions
@@ -3325,7 +3325,9 @@ class P4Sync(Command, P4UserMap): if currentChange < change: earliestCommit = "^%s" % next else: - latestCommit = "%s" % next + if next == latestCommit: + die("Infinite loop while looking in ref %s for change %s. Check your branch mappings" % (ref, change)) + latestCommit = "%s^@" % next return "" |