From 37b9dcabfc48b0cbce638140279878dac37aec73 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Wed, 22 Apr 2020 18:25:45 -0600 Subject: shallow.c: use '{commit,rollback}_shallow_file' In bd0b42aed3 (fetch-pack: do not take shallow lock unnecessarily, 2019-01-10), the author noted that 'is_repository_shallow' produces visible side-effect(s) by setting 'is_shallow' and 'shallow_stat'. This is a problem for e.g., fetching with '--update-shallow' in a shallow repository with 'fetch.writeCommitGraph' enabled, since the update to '.git/shallow' will cause Git to think that the repository isn't shallow when it is, thereby circumventing the commit-graph compatibility check. This causes problems in shallow repositories with at least shallow refs that have at least one ancestor (since the client won't have those objects, and therefore can't take the reachability closure over commits when writing a commit-graph). Address this by introducing thin wrappers over 'commit_lock_file' and 'rollback_lock_file' for use specifically when the lock is held over '.git/shallow'. These wrappers (appropriately called 'commit_shallow_file' and 'rollback_shallow_file') call into their respective functions in 'lockfile.h', but additionally reset validity checks used by the shallow machinery. Replace each instance of 'commit_lock_file' and 'rollback_lock_file' with 'commit_shallow_file' and 'rollback_shallow_file' when the lock being held is over the '.git/shallow' file. As a result, 'prune_shallow' can now only be called once (since 'check_shallow_file_for_update' will die after calling 'reset_repository_shallow'). But, this is OK since we only call 'prune_shallow' at most once per process. Helped-by: Jonathan Tan Helped-by: Junio C Hamano Signed-off-by: Taylor Blau Reviewed-by: Jonathan Tan Signed-off-by: Junio C Hamano --- commit.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'commit.h') diff --git a/commit.h b/commit.h index 008a0fa4a0..ab91d21131 100644 --- a/commit.h +++ b/commit.h @@ -249,6 +249,8 @@ struct oid_array; struct ref; int register_shallow(struct repository *r, const struct object_id *oid); int unregister_shallow(const struct object_id *oid); +int commit_shallow_file(struct repository *r, struct lock_file *lk); +void rollback_shallow_file(struct repository *r, struct lock_file *lk); int for_each_commit_graft(each_commit_graft_fn, void *); int is_repository_shallow(struct repository *r); struct commit_list *get_shallow_commits(struct object_array *heads, -- cgit v1.2.3