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

Re: [PATCH v6 5/8] fetch: protect branches checked out in all worktrees

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 16, 2021, 05:49 UTC
Message-ID
<xmqq1r3gd50r.fsf@gitster.g>
In-Reply-To
<20211113033358.2179376-6-andersk@mit.edu>
Anders Kaseorg <andersk@mit.edu> writes:
Show 10 quoted lines
> Refuse to fetch into the currently checked out branch of any working
> tree, not just the current one.
>
> Fixes this previously reported bug:
>
> https://public-inbox.org/git/cb957174-5e9a-5603-ea9e-ac9b58a2eaad@mathema.de
>
> As a side effect of using find_shared_symref, we’ll also refuse the
> fetch when we’re on a detached HEAD because we’re rebasing or bisecting
> on the branch in question. This seems like a sensible change.
Indeed.
Show 36 quoted lines
> Signed-off-by: Anders Kaseorg <andersk@mit.edu>
> ---
>  builtin/fetch.c       | 75 +++++++++++++++++++++++--------------------
>  t/t5516-fetch-push.sh | 18 +++++++++++
>  2 files changed, 58 insertions(+), 35 deletions(-)
>
> diff --git a/builtin/fetch.c b/builtin/fetch.c
> index e5971fa6e5..f373252490 100644
> --- a/builtin/fetch.c
> +++ b/builtin/fetch.c
> @@ -28,6 +28,7 @@
>  #include "promisor-remote.h"
>  #include "commit-graph.h"
>  #include "shallow.h"
> +#include "worktree.h"
>  
>  #define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000)
>  
> @@ -840,14 +841,13 @@ static void format_display(struct strbuf *display, char code,
>  
>  static int update_local_ref(struct ref *ref,
>  			    struct ref_transaction *transaction,
> -			    const char *remote,
> -			    const struct ref *remote_ref,
> -			    struct strbuf *display,
> -			    int summary_width)
> +			    const char *remote, const struct ref *remote_ref,
> +			    struct strbuf *display, int summary_width,
> +			    struct worktree **worktrees)
>  {
>  	struct commit *current = NULL, *updated;
>  	enum object_type type;
> -	struct branch *current_branch = branch_get(NULL);
> +	const struct worktree *wt;
>  	const char *pretty_ref = prettify_refname(ref->name);
>  	int fast_forward = 0;
Having to pass the parameter down to here through the
    ->do_fetch()
      ->backfill_tags() (or do_fetch() itself)
        ->consume_refs()
          ->store_updated_refs()
            ->update_local_ref()

callchain makes the "damage to the code" by the patch look larger than it actually is. The real change is ...

Show 11 quoted lines
> @@ -862,16 +862,17 @@ static int update_local_ref(struct ref *ref,
>  		return 0;
>  	}
>  
> -	if (current_branch &&
> -	    !strcmp(ref->name, current_branch->name) &&
> -	    !(update_head_ok || is_bare_repository()) &&
> -	    !is_null_oid(&ref->old_oid)) {
> +	if (!update_head_ok &&
> +	    (wt = find_shared_symref(worktrees, "HEAD", ref->name)) &&
> +	    !wt->is_bare && !is_null_oid(&ref->old_oid)) {
... this part, which looks very sensible.
Show 11 quoted lines
>  		 * If this is the head, and it's not okay to update
>  		 * the head, and the old value of the head isn't empty...
>  		 */
>  		format_display(display, '!', _("[rejected]"),
> -			       _("can't fetch in current branch"),
> +			       wt->is_current ?
> +				       _("can't fetch in current branch") :
> +				       _("checked out in another worktree"),
>  			       remote, pretty_ref, summary_width);
>  		return 1;
>  	}
Show 7 quoted lines
> @@ -1643,7 +1647,7 @@ static int do_fetch(struct transport *transport,
>  				  "you need to specify exactly one branch with the --set-upstream option"));
>  		}
>  	}
> - skip:
> +skip:
>  	free_refs(ref_map);
;-)

I count 30 hits of "^ [a-z0-9]*:" and 255 hits of "^[a-z0-9]*:" in our codebase. It must be some developers used to subscribe to "don't place the label abut the left edge" school but no longer, or something like that.

The code changes all look good to me.
Thanks.
Show 27 quoted lines
> diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
> index 4db8edd9c8..36fb90f4b0 100755
> --- a/t/t5516-fetch-push.sh
> +++ b/t/t5516-fetch-push.sh
> @@ -1770,4 +1770,22 @@ test_expect_success 'denyCurrentBranch and worktrees' '
>  	git -C cloned push origin HEAD:new-wt &&
>  	test_must_fail git -C cloned push --delete origin new-wt
>  '
> +
> +test_expect_success 'refuse fetch to current branch of worktree' '
> +	test_when_finished "git worktree remove --force wt && git branch -D wt" &&
> +	git worktree add wt &&
> +	test_commit apple &&
> +	test_must_fail git fetch . HEAD:wt &&
> +	git fetch -u . HEAD:wt
> +'
> +
> +test_expect_success 'refuse fetch to current branch of bare repository worktree' '
> +	test_when_finished "rm -fr bare.git" &&
> +	git clone --bare . bare.git &&
> +	git -C bare.git worktree add wt &&
> +	test_commit banana &&
> +	test_must_fail git -C bare.git fetch .. HEAD:wt &&
> +	git -C bare.git fetch -u .. HEAD:wt
> +'
> +
>  test_done
Previous: Anders KaseorgNext: Anders Kaseorg
Message 10 of 21 in “protect branches checked out in all worktrees”
  1. 0/8 protect branches checked out in all worktreesAnders Kaseorg, Nov 13, 2021
  2. 1/8 fetch: lowercase error messagesAnders Kaseorg, Nov 13, 2021
  3. Junio C HamanoNov 16, 2021
  4. Anders KaseorgNov 16, 2021
  5. Junio C HamanoNov 17, 2021
  6. Jiang XinNov 22, 2021
  7. 2/8 receive-pack: lowercase error messagesAnders Kaseorg, Nov 13, 2021
  8. Junio C HamanoNov 18, 2021
  9. 5/8 fetch: protect branches checked out in all worktreesAnders Kaseorg, Nov 13, 2021
  10. Junio C HamanoNov 16, 2021
  11. Anders KaseorgNov 16, 2021
  12. Johannes SchindelinNov 22, 2021
  13. 3/8 branch: lowercase error messagesAnders Kaseorg, Nov 13, 2021
  14. 6/8 receive-pack: clean dead code from update_worktree()Anders Kaseorg, Nov 13, 2021
  15. Junio C HamanoNov 16, 2021
  16. 7/8 receive-pack: protect current branch for bare repository worktreeAnders Kaseorg, Nov 13, 2021
  17. 4/8 worktree: simplify find_shared_symref() memory ownership modelAnders Kaseorg, Nov 13, 2021
  18. Junio C HamanoNov 16, 2021
  19. Johannes SchindelinNov 22, 2021
  20. 8/8 branch: protect branches checked out in all worktreesAnders Kaseorg, Nov 13, 2021
  21. Johannes SchindelinNov 22, 2021

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.