git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 07/28] shallow.c: add remove_reachable_shallow_points()

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 25, 2013, 21:53 UTC
Message-ID
<xmqqpppow3kv.fsf@gitster.dls.corp.google.com>
In-Reply-To
<1385351754-9954-8-git-send-email-pclouds@gmail.com>
Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:
Show 21 quoted lines
> When we receive a pack and the shallow points from another repository,
> we may want to add more shallow points to current repo to make sure no
> commits point to nowhere. However we do not want to add unnecessary
> shallow points and cut our history short because the other end is a
> shallow version of this repo. The output shallow points may or may not
> be added to .git/shallow, depending on whether they are actually
> reachable in the new pack.
>
> This function filters such shallow points out, leaving ones that might
> potentially be added. A simple has_sha1_file won't do because we may
> have incomplete object islands (i.e. not connected to any refs) and
> the shallow points are on these islands. In that case we want to keep
> the shallow points as candidates until we figure out if the new pack
> connects to such object islands.
>
> Typical cases that use remove_reachable_shallow_points() are:
>
>  - fetch from a repo that has longer history: in this case all remote
>    shallow roots do not exist in the client repo, this function will
>    be cheap as it just does a few lookup_commit_graft and
>    has_sha1_file.

It is unclear why. If you fetched from a repository more complete than you, you may deepen your history which may allow you to unplug the shallow points you originally had, and remote "shallow root" (by the way, lets find a single good phrase to represent this thing and stick to it) may want to replace them, no?

Show 5 quoted lines
>  - fetch from a repo that has exactly the same shallow root set
>    (e.g. a clone from a shallow repo): this case may trigger
>    in_merge_bases_many all the way to roots. An exception is made to
>    avoid such costly path with a faith that .git/shallow does not
>    usually points to unreachable commit islands.

... and when the faith is broken, you will end up with a broken repository???

Show 97 quoted lines
>  - push from a shallow repo that has shorter history than the
>    server's: in_merge_bases_many() is unavoidable, so the longer
>    history the client has the higher the server cost is. The cost may
>    be reduced with the help of pack bitmaps, or commit cache, though.
>
>  - push from a shallow clone that has exactly the same shallow root
>    set: the same as the second fetch case above, .i.e. cheap by
>    exception.
>
> The function must be called before the new pack is installed, or we
> won't know which objects are ours, which theirs.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
>  commit.h  |  3 +++
>  connect.c |  2 +-
>  remote.h  |  1 +
>  shallow.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/commit.h b/commit.h
> index a879526..98044e6 100644
> --- a/commit.h
> +++ b/commit.h
> @@ -193,6 +193,7 @@ extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
>  /* largest positive number a signed 32-bit integer can contain */
>  #define INFINITE_DEPTH 0x7fffffff
>  
> +struct extra_have_objects;
>  extern int register_shallow(const unsigned char *sha1);
>  extern int unregister_shallow(const unsigned char *sha1);
>  extern int for_each_commit_graft(each_commit_graft_fn, void *);
> @@ -206,6 +207,8 @@ extern void setup_alternate_shallow(struct lock_file *shallow_lock,
>  				    const char **alternate_shallow_file);
>  extern char *setup_temporary_shallow(void);
>  extern void advertise_shallow_grafts(int);
> +extern void remove_reachable_shallow_points(struct extra_have_objects *out,
> +					    const struct extra_have_objects *in);
>  
>  int is_descendant_of(struct commit *, struct commit_list *);
>  int in_merge_bases(struct commit *, struct commit *);
> diff --git a/connect.c b/connect.c
> index d0602b0..80e4360 100644
> --- a/connect.c
> +++ b/connect.c
> @@ -45,7 +45,7 @@ int check_ref_type(const struct ref *ref, int flags)
>  	return check_ref(ref->name, strlen(ref->name), flags);
>  }
>  
> -static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1)
> +void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1)
>  {
>  	ALLOC_GROW(extra->array, extra->nr + 1, extra->alloc);
>  	hashcpy(&(extra->array[extra->nr][0]), sha1);
> diff --git a/remote.h b/remote.h
> index 773faa9..ff604ff 100644
> --- a/remote.h
> +++ b/remote.h
> @@ -145,6 +145,7 @@ extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
>  				     struct ref **list, unsigned int flags,
>  				     struct extra_have_objects *have,
>  				     struct extra_have_objects *shallow);
> +extern void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1);
>  
>  int resolve_remote_symref(struct ref *ref, struct ref *list);
>  int ref_newer(const unsigned char *new_sha1, const unsigned char *old_sha1);
> diff --git a/shallow.c b/shallow.c
> index 9552512..a974d2d 100644
> --- a/shallow.c
> +++ b/shallow.c
> @@ -2,6 +2,8 @@
>  #include "commit.h"
>  #include "tag.h"
>  #include "pkt-line.h"
> +#include "remote.h"
> +#include "refs.h"
>  
>  static int is_shallow = -1;
>  static struct stat shallow_stat;
> @@ -235,3 +237,46 @@ void advertise_shallow_grafts(int fd)
>  		return;
>  	for_each_commit_graft(advertise_shallow_grafts_cb, &fd);
>  }
> +
> +struct commit_array {
> +	struct commit **commits;
> +	int nr, alloc;
> +};
> +
> +static int add_ref(const char *refname,
> +		   const unsigned char *sha1, int flags, void *cb_data)
> +{
> +	struct commit_array *ca = cb_data;
> +	ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc);
> +	ca->commits[ca->nr++] = lookup_commit(sha1);
> +	return 0;
> +}

Can't a ref point at a non-commit-ish? Is the code prepared to deal with such an entry (possibly a NULL pointer) in the commit_array struct?

Show 28 quoted lines
> +void remove_reachable_shallow_points(struct extra_have_objects *out,
> +				     const struct extra_have_objects *in)
> +{
> +	struct commit_array ca;
> +	int i;
> +
> +	memset(&ca, 0, sizeof(ca));
> +	head_ref(add_ref, &ca);
> +	for_each_ref(add_ref, &ca);
> +	for (i = 0; i < in->nr; i++) {
> +		struct commit_graft *graft = lookup_commit_graft(in->array[i]);
> +		/*
> +		 * For a clone from a shallow upstream, the clone has
> +		 * the same shallow roots as upstream and it will
> +		 * trigger in_merge_bases_many() all the way to roots.
> +		 * Avoid that costly path and assume .git/shallow is
> +		 * good most of the time.
> +		 */
> +		if (graft && graft->nr_parent < 0)
> +			continue;
> +		if (has_sha1_file(in->array[i]) &&
> +		    in_merge_bases_many(lookup_commit(in->array[i]),
> +					ca.nr, ca.commits))
> +			continue;
> +		add_extra_have(out, in->array[i]);
> +	}
> +	free(ca.commits);
> +}
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 15 of 79 in “First class shallow clone”
  1. 00/28 First class shallow cloneNguyễn Thái Ngọc Duy, Nov 25, 2013
  2. 01/28 transport.h: remove send_pack prototype, already defined in send-pack.hNguyễn Thái Ngọc Duy, Nov 25, 2013
  3. 02/28 send-pack: forbid pushing from a shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  4. 03/28 clone: prevent --reference to a shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  5. Eric SunshineNov 26, 2013
  6. 04/28 update-server-info: do not publish shallow clonesNguyễn Thái Ngọc Duy, Nov 25, 2013
  7. Junio C HamanoNov 25, 2013
  8. Duy NguyenNov 26, 2013
  9. 05/28 Advertise shallow graft information on the server endNguyễn Thái Ngọc Duy, Nov 25, 2013
  10. 06/28 connect.c: teach get_remote_heads to parse "shallow" linesNguyễn Thái Ngọc Duy, Nov 25, 2013
  11. Junio C HamanoNov 25, 2013
  12. Junio C HamanoNov 25, 2013
  13. Duy NguyenNov 27, 2013
  14. 07/28 shallow.c: add remove_reachable_shallow_points()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  15. Junio C HamanoNov 25, 2013
  16. 08/28 shallow.c: add mark_new_shallow_refs()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  17. Junio C HamanoNov 25, 2013
  18. Duy NguyenNov 26, 2013
  19. Junio C HamanoNov 26, 2013
  20. 09/28 shallow.c: extend setup_*_shallow() to accept extra shallow pointsNguyễn Thái Ngọc Duy, Nov 25, 2013
  21. Junio C HamanoNov 25, 2013
  22. 10/28 fetch-pack.c: move shallow update code out of fetch_pack()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  23. 11/28 fetch-pack.h: one statement per bitfield declarationNguyễn Thái Ngọc Duy, Nov 25, 2013
  24. 12/28 clone: support remote shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  25. 13/28 fetch: support fetching from a shallow repositoryNguyễn Thái Ngọc Duy, Nov 25, 2013
  26. Eric SunshineNov 27, 2013
  27. 14/28 upload-pack: make sure deepening preserves shallow rootsNguyễn Thái Ngọc Duy, Nov 25, 2013
  28. 15/28 fetch: add --update-shallow to get refs that require updating .git/shallowNguyễn Thái Ngọc Duy, Nov 25, 2013
  29. Eric SunshineNov 27, 2013
  30. Duy NguyenNov 27, 2013
  31. Junio C HamanoNov 27, 2013
  32. 16/28 receive-pack: reorder some code in unpack()Nguyễn Thái Ngọc Duy, Nov 25, 2013
  33. Junio C HamanoDec 2, 2013
  34. 17/28 Support pushing from a shallow cloneNguyễn Thái Ngọc Duy, Nov 25, 2013
  35. Eric SunshineNov 26, 2013
  36. 18/28 New var GIT_SHALLOW_FILE to propagate --shallow-file to subprocessesNguyễn Thái Ngọc Duy, Nov 25, 2013
  37. 19/28 connected.c: add new variant that runs with --shallow-fileNguyễn Thái Ngọc Duy, Nov 25, 2013
  38. 20/28 receive-pack: allow pushing with new shallow rootsNguyễn Thái Ngọc Duy, Nov 25, 2013
  39. 21/28 send-pack: support pushing to a shallow cloneNguyễn Thái Ngọc Duy, Nov 25, 2013
  40. 22/28 remote-curl: pass ref SHA-1 to fetch-pack as wellNguyễn Thái Ngọc Duy, Nov 25, 2013
  41. 23/28 Support fetch/clone over httpNguyễn Thái Ngọc Duy, Nov 25, 2013
  42. 24/28 receive-pack: support pushing to a shallow clone via httpNguyễn Thái Ngọc Duy, Nov 25, 2013
  43. 25/28 send-pack: support pushing from a shallow clone via httpNguyễn Thái Ngọc Duy, Nov 25, 2013
  44. 26/28 git-clone.txt: remove shallow clone limitationsNguyễn Thái Ngọc Duy, Nov 25, 2013
  45. 27/28 clone: use git protocol for cloning shallow repo locallyNguyễn Thái Ngọc Duy, Nov 25, 2013
  46. Eric SunshineNov 27, 2013
  47. 28/28 prune: clean .git/shallow after pruning objectsNguyễn Thái Ngọc Duy, Nov 25, 2013
  48. 00/28 First class shallow cloneNguyễn Thái Ngọc Duy, Dec 5, 2013
  49. 01/28 transport.h: remove send_pack prototype, already defined in send-pack.hNguyễn Thái Ngọc Duy, Dec 5, 2013
  50. 02/28 Replace struct extra_have_objects with struct sha1_arrayNguyễn Thái Ngọc Duy, Dec 5, 2013
  51. 03/28 send-pack: forbid pushing from a shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  52. 04/28 clone: prevent --reference to a shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  53. 05/28 Make the sender advertise shallow commits to the receiverNguyễn Thái Ngọc Duy, Dec 5, 2013
  54. 06/28 connect.c: teach get_remote_heads to parse "shallow" linesNguyễn Thái Ngọc Duy, Dec 5, 2013
  55. 07/28 shallow.c: extend setup_*_shallow() to accept extra shallow commitsNguyễn Thái Ngọc Duy, Dec 5, 2013
  56. 08/28 shallow.c: the 8 steps to select new commits for .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  57. 09/28 shallow.c: steps 6 and 7 to select new commits for .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  58. 10/28 fetch-pack.c: move shallow update code out of fetch_pack()Nguyễn Thái Ngọc Duy, Dec 5, 2013
  59. 11/28 fetch-pack.h: one statement per bitfield declarationNguyễn Thái Ngọc Duy, Dec 5, 2013
  60. 12/28 clone: support remote shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  61. 13/28 fetch: support fetching from a shallow repositoryNguyễn Thái Ngọc Duy, Dec 5, 2013
  62. 14/28 upload-pack: make sure deepening preserves shallow rootsNguyễn Thái Ngọc Duy, Dec 5, 2013
  63. 15/28 fetch: add --update-shallow to accept refs that update .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  64. 16/28 receive-pack: reorder some code in unpack()Nguyễn Thái Ngọc Duy, Dec 5, 2013
  65. 17/28 receive/send-pack: support pushing from a shallow cloneNguyễn Thái Ngọc Duy, Dec 5, 2013
  66. 18/28 New var GIT_SHALLOW_FILE to propagate --shallow-file to subprocessesNguyễn Thái Ngọc Duy, Dec 5, 2013
  67. 19/28 connected.c: add new variant that runs with --shallow-fileNguyễn Thái Ngọc Duy, Dec 5, 2013
  68. 20/28 receive-pack: allow pushes that update .git/shallowNguyễn Thái Ngọc Duy, Dec 5, 2013
  69. 21/28 send-pack: support pushing to a shallow cloneNguyễn Thái Ngọc Duy, Dec 5, 2013
  70. 22/28 remote-curl: pass ref SHA-1 to fetch-pack as wellNguyễn Thái Ngọc Duy, Dec 5, 2013
  71. 23/28 Support shallow fetch/clone over smart-httpNguyễn Thái Ngọc Duy, Dec 5, 2013
  72. Jeff KingJan 8, 2014
  73. t5537: fix incorrect expectation in test case 10Nguyễn Thái Ngọc Duy, Jan 8, 2014
  74. Jeff KingJan 9, 2014
  75. 24/28 receive-pack: support pushing to a shallow clone via httpNguyễn Thái Ngọc Duy, Dec 5, 2013
  76. 25/28 send-pack: support pushing from a shallow clone via httpNguyễn Thái Ngọc Duy, Dec 5, 2013
  77. 26/28 clone: use git protocol for cloning shallow repo locallyNguyễn Thái Ngọc Duy, Dec 5, 2013
  78. 27/28 prune: clean .git/shallow after pruning objectsNguyễn Thái Ngọc Duy, Dec 5, 2013
  79. 28/28 git-clone.txt: remove shallow clone limitationsNguyễn Thái Ngọc Duy, Dec 5, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.