git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Glen Choo <chooglen@google.com>
To: Jonathan Tan <jonathantanmy@google.com>
Cc: git@vger.kernel.org, jonathantanmy@google.com,
	steadmon@google.com, emilyshaffer@google.com, avarab@gmail.com,
	levraiphilippeblain@gmail.com, gitster@pobox.com
Subject: Re: [PATCH v6 5/5] branch: add --recurse-submodules option for branch creation
Date: Tue, 11 Jan 2022 10:11:08 -0800	[thread overview]
Message-ID: <kl6l4k6akurn.fsf@chooglen-macbookpro.roam.corp.google.com> (raw)
In-Reply-To: <20220111032842.1247928-1-jonathantanmy@google.com>

Jonathan Tan <jonathantanmy@google.com> writes:

> I am not very familiar with branch tracking, so I'll review everything
> except that part.
>
> Glen Choo <chooglen@google.com> writes:
>> Although this commit does not introduce breaking changes, it is
>> incompatible with existing --recurse-submodules semantics e.g. `git
>> checkout` does not recursively checkout the expected branches created by
>> `git branch` yet. 
>
> Probably worth explaining that it will not recursively checkout the
> expected branches *if* any of them are subsequently updated. Maybe say:
>
>   If a user were to create branches in this way, create a commit on the
>   branch in a submodule, and run "git checkout --recurse-submodules" in
>   the superproject, the commits to be checked out (which are based on
>   the gitlink in the superproject, not on the ref store of the
>   submodule) probably wouldn't match the user's expectation.
>
>> To ensure that the correct set of semantics is used,
>> this commit introduces a new configuration value,
>> `submodule.propagateBranches`, which enables submodule branching when
>> true (defaults to false).
>
> And then this could be reworded to:
>
>   Because of this, this commit introduces a new configuration value
>   `submodule.propagateBranches`. The plan is for Git commands to
>   prioritize submodule ref store information over superproject gitlink
>   if this is true. Because "git branch --recurse-submodules" writes to
>   submodule ref stores, for the sake of clarity, it will not function
>   unless this configuration value is set.

Thanks! I'll use this wording - otherwise it might not be clear to
readers what the difference in 'semantics' refers to.

>
>> @@ -71,6 +68,23 @@ submodule.recurse::
>>  	`git fetch` but does not have a `--no-recurse-submodules` option.
>>  	For these commands a workaround is to temporarily change the
>>  	configuration value by using `git -c submodule.recurse=0`.
>> +	+
>> +	The following list shows the commands that accept
>> +	`--recurse-submodules` and whether they are supported by this
>> +	setting.
>> +	* `checkout`, `fetch`, `grep`, `pull`, `push`, `read-tree`,
>> +	`reset`, `restore` and `switch` are always supported.
>> +	* `clone` and `ls-files` are not supported.
>> +	* `branch` is supported only if `submodule.propagateBranches` is
>> +	enabled
>
> One oddity is that paragraphs after the "+" cannot be indented - see
> other documentation files for examples.

Ah, thanks for the catch. Interestingly, it still rendered as expected
when I ran `make` - perhaps a deviation from the asciidoc spec.

>> diff --git a/branch.c b/branch.c
>> index 55c7ba4a25..6d0d9a8e1b 100644
>> --- a/branch.c
>> +++ b/branch.c
>> @@ -8,6 +8,8 @@
>>  #include "sequencer.h"
>>  #include "commit.h"
>>  #include "worktree.h"
>> +#include "submodule-config.h"
>> +#include "run-command.h"
>>  
>>  struct tracking {
>>  	struct refspec_item spec;
>> @@ -478,6 +480,134 @@ void dwim_and_setup_tracking(struct repository *r, const char *new_ref,
>>  	setup_tracking(new_ref, real_orig_ref, track, quiet);
>>  }
>>  
>> +/**
>> + * Creates a branch in a submodule by calling
>> + * create_branches_recursively() in a child process. The child process
>> + * is necessary because install_branch_config() (and its variants) do
>> + * not support writing configs to submodules.
>> + */
>
> Makes sense that we need a child process, but could the child process be
> "branch" instead of "submodule--helper"? If not, also mention why.

I'll mention why it has to be "submodule--helper"; I can see why a
reader might wonder this.

> As for the reason, probably better to explicitly mention
> install_branch_config_multiple_remotes() and say "(which is called by
> setup_tracking())".

Sounds good.

>> diff --git a/t/t3207-branch-submodule.sh b/t/t3207-branch-submodule.sh
>> new file mode 100755
>> index 0000000000..a2dfb5ad7f
>> --- /dev/null
>> +++ b/t/t3207-branch-submodule.sh
>> @@ -0,0 +1,291 @@
>> +#!/bin/sh
>> +
>> +test_description='git branch submodule tests'
>> +
>> +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
>> +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
>> +
>> +. ./test-lib.sh
>> +. "$TEST_DIRECTORY"/lib-rebase.sh
>> +
>> +test_expect_success 'setup superproject and submodule' '
>> +	git init super &&
>> +	test_commit foo &&
>> +	git init sub-sub-upstream &&
>> +	test_commit -C sub-sub-upstream foo &&
>> +	git init sub-upstream &&
>> +	# Submodule in a submodule
>> +	git -C sub-upstream submodule add "$TRASH_DIRECTORY/sub-sub-upstream" sub-sub &&
>> +	git -C sub-upstream commit -m "add submodule" &&
>> +	# Regular submodule
>> +	git -C super submodule add "$TRASH_DIRECTORY/sub-upstream" sub &&
>> +	# Submodule in a subdirectory
>> +	git -C super submodule add "$TRASH_DIRECTORY/sub-sub-upstream" second/sub &&
>> +	git -C super commit -m "add submodule" &&
>> +	git -C super config submodule.propagateBranches true &&
>> +	git -C super/sub submodule update --init
>> +'
>> +
>> +CLEANUP_SCRIPT_PATH="$TRASH_DIRECTORY/cleanup_branches.sh"
>> +
>> +cat >"$CLEANUP_SCRIPT_PATH" <<'EOF'
>> +	#!/bin/sh
>> +
>> +	super_dir="$1"
>> +	shift
>> +	(
>> +		cd "$super_dir" &&
>> +		git checkout main &&
>> +		for branch_name in "$@"; do
>> +			git branch -D "$branch_name"
>> +			git submodule foreach "$TRASH_DIRECTORY/cleanup_branches.sh . $branch_name || true"
>> +		done
>> +	)
>> +EOF
>> +chmod +x "$CLEANUP_SCRIPT_PATH"
>> +
>> +cleanup_branches() {
>> +	TRASH_DIRECTORY="\"$TRASH_DIRECTORY\"" "$CLEANUP_SCRIPT_PATH" "$@"
>> +} >/dev/null 2>/dev/null
>
> I don't think that the cleanup is saving much in process invocation
> anymore - could we just delete the whole thing and start anew in each
> test?
>
> The rest of the tests are assuming that the cleanup works as expected -
> I didn't take a close look.

Hm, you're right - deleting the branches is already quite slow, starting
anew would be easier and might not be much slower. I'll test the
'starting anew' approach to make sure it's not too slow.

> Also, you should probably use "$(pwd)" instead of $TRASH_DIRECTORY.

Thanks!

>> +test_expect_success '--recurse-submodules should fail when not creating branches' '
>> +	test_when_finished "cleanup_branches super branch-a" &&
>> +	(
>> +		cd super &&
>> +		git branch --recurse-submodules branch-a &&
>> +		test_must_fail git branch --recurse-submodules -D branch-a &&
>> +		# Assert that the branches were not deleted
>> +		git rev-parse --abbrev-ref branch-a &&
>> +		git -C sub rev-parse --abbrev-ref branch-a
>> +	)
>> +'
>
> If we're just checking that the ref exists, no need for "--abbrev-ref".
> Same comment throughout the file.

Ah yes, thanks.

>> +test_expect_success 'should not create any branches if branch is not valid for all repos' '
>> +	test_when_finished "cleanup_branches super branch-a" &&
>> +	(
>> +		cd super &&
>> +		git -C sub branch branch-a &&
>> +		test_must_fail git branch --recurse-submodules branch-a 2>actual &&
>> +		test_must_fail git rev-parse branch-a &&
>> +
>> +		cat >expected <<-EOF &&
>> +		submodule ${SQ}sub${SQ}: fatal: A branch named ${SQ}branch-a${SQ} already exists.
>> +		fatal: submodule ${SQ}sub${SQ}: cannot create branch ${SQ}branch-a${SQ}
>> +		EOF
>> +		test_cmp expected actual
>> +	)
>> +'
>
> The error message seems too specific - probably enough to grep for the
> information about the branch already existing.

Makes sense.

>
>> +test_expect_success 'should create branches if branch exists and --force is given' '
>> +	test_when_finished "cleanup_branches super branch-a" &&
>> +	(
>> +		cd super &&
>> +		git -C sub rev-parse HEAD >expected &&
>> +		test_commit -C sub baz &&
>> +		git -C sub branch branch-a HEAD~1 &&
>> +		git branch --recurse-submodules --force branch-a &&
>> +		git rev-parse branch-a &&
>> +		# assert that sub:branch-a was moved
>> +		git -C sub rev-parse branch-a >actual &&
>> +		test_cmp expected actual
>> +	)
>> +'
>
> Should we create branch-a at HEAD instead of HEAD~1?

If we create branch-a at HEAD, we won't be testing that --force moves
the branch head. This means that the test might pass if we simply ignore
any existing branch-a - which is not the intended behavior of --force,
but this is behavior that we might want in the future (probably using
another option).

>> +test_expect_success 'should create branch when submodule is not in HEAD:.gitmodules' '
>> +	test_when_finished "cleanup_branches super branch-a branch-b branch-c" &&
>> +	(
>> +		cd super &&
>> +		git branch branch-a &&
>> +		git checkout -b branch-b &&
>> +		git submodule add ../sub-upstream sub2 &&
>> +		git -C sub2 submodule update --init &&
>> +		# branch-b now has a committed submodule not in branch-a
>> +		git commit -m "add second submodule" &&
>> +		git checkout branch-a &&
>> +		git branch --recurse-submodules branch-c branch-b &&
>> +		git rev-parse branch-c &&
>> +		git -C sub rev-parse branch-c &&
>> +		git -C second/sub rev-parse branch-c &&
>> +		git checkout --recurse-submodules branch-c &&
>> +		git -C sub2 rev-parse branch-c &&
>> +		git -C sub2/sub-sub rev-parse branch-c
>> +	)
>> +'
>
> No need to check so many repos, I think - just sub2 will do.

Hm yes, there isn't a reason to think that the branch wouldn't be
created in the other repos.

>
> [skip tracking tests]
>
>> +test_expect_success 'should not create branches in inactive submodules' '
>> +	test_when_finished "cleanup_branches super branch-a" &&
>> +	test_config -C super submodule.sub.active false &&
>> +	(
>> +		cd super &&
>> +		git branch --recurse-submodules branch-a &&
>> +		git rev-parse branch-a &&
>> +		test_must_fail git -C sub branch-a
>> +	)
>> +'
>
> Makes sense, but could all the tracking tests be together in the file?
> Or is this order for a reason?

No, you're right, the order doesn't make sense. I'll move this to before
the tracking tests.

>> +test_expect_success 'setup remote-tracking tests' '
>
> This setup is not just for remote-tracking tests.

Yes, this is misleading, thanks.

>
>> +	(
>> +		cd super &&
>> +		git branch branch-a &&
>> +		git checkout -b branch-b &&
>> +		git submodule add ../sub-upstream sub2 &&
>> +		# branch-b now has a committed submodule not in branch-a
>> +		git commit -m "add second submodule"
>> +	) &&
>> +	git clone --branch main --recurse-submodules super super-clone &&
>> +	git -C super-clone config submodule.propagateBranches true
>> +'
>> +
>> +test_expect_success 'should not create branch when submodule is not in .git/modules' '
>
> I understand that no branch is created, but the title is ambiguous, to
> me, whether it is a fatal error or not. Maybe the title should be "fatal
> error upon branch creation when submodule is not in .git/modules".

Ok, makes sense.

>
>> +	# The cleanup needs to delete sub2 separately because main does not have sub2
>> +	test_when_finished "git -C super-clone/sub2 branch -D branch-b && \
>> +		git -C super-clone/sub2/sub-sub branch -D branch-b && \
>> +		cleanup_branches super-clone branch-a branch-b" &&
>> +	(
>> +		cd super-clone &&
>> +		# This should succeed because super-clone has sub.
>
> "has sub in .git/modules", I think.
>
>> +		git branch --recurse-submodules branch-a origin/branch-a &&
>> +		# This should fail because super-clone does not have sub2.
>
> Likewise.

Ah, yes, it might be confusing otherwise.

  reply	other threads:[~2022-01-11 18:11 UTC|newest]

Thread overview: 110+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-22 22:32 [PATCH 0/4] implement branch --recurse-submodules Glen Choo
2021-11-22 22:32 ` [PATCH 1/4] submodule-config: add submodules_of_tree() helper Glen Choo
2021-11-23  2:12   ` Jonathan Tan
2021-11-23 19:48     ` Glen Choo
2021-11-23 10:53   ` Ævar Arnfjörð Bjarmason
2021-11-23 18:35     ` Glen Choo
2021-11-23 22:46   ` Junio C Hamano
2021-11-22 22:32 ` [PATCH 2/4] branch: refactor out branch validation from create_branch() Glen Choo
2021-11-22 22:32 ` [PATCH 3/4] branch: add --dry-run option to branch Glen Choo
2021-11-23 10:42   ` Ævar Arnfjörð Bjarmason
2021-11-23 18:42     ` Glen Choo
2021-11-23 23:10   ` Jonathan Tan
2021-11-24  0:52     ` Glen Choo
2021-11-22 22:32 ` [PATCH 4/4] branch: add --recurse-submodules option for branch creation Glen Choo
2021-11-23 10:45   ` Ævar Arnfjörð Bjarmason
2021-11-23 18:56     ` Glen Choo
2021-11-23 19:41   ` Philippe Blain
2021-11-23 23:43     ` Glen Choo
2021-11-24  1:31   ` Jonathan Tan
2021-11-24 18:18     ` Glen Choo
2021-11-29 21:01       ` Jonathan Tan
2021-12-06 21:55 ` [PATCH v2 0/3] implement branch --recurse-submodules Glen Choo
2021-12-06 21:55   ` [PATCH v2 1/3] branch: move --set-upstream-to behavior to setup_tracking() Glen Choo
2021-12-06 22:48     ` Junio C Hamano
2021-12-08 18:48       ` Glen Choo
2021-12-06 23:28     ` Junio C Hamano
2021-12-08 17:09       ` Glen Choo
2021-12-06 21:55   ` [PATCH v2 2/3] builtin/branch: clean up action-picking logic in cmd_branch() Glen Choo
2021-12-06 21:55   ` [PATCH v2 3/3] branch: add --recurse-submodules option for branch creation Glen Choo
2021-12-09 18:49   ` [PATCH v3 0/5] implement branch --recurse-submodules Glen Choo
2021-12-09 18:49     ` [PATCH v3 1/5] branch: move --set-upstream-to behavior to setup_tracking() Glen Choo
2021-12-09 21:19       ` Jonathan Tan
2021-12-09 22:16         ` Glen Choo
2021-12-09 18:49     ` [PATCH v3 2/5] branch: remove forward declaration of validate_branch_start() Glen Choo
2021-12-09 18:49     ` [PATCH v3 3/5] builtin/branch: clean up action-picking logic in cmd_branch() Glen Choo
2021-12-09 21:23       ` Jonathan Tan
2021-12-09 21:57         ` Glen Choo
2021-12-09 18:49     ` [PATCH v3 4/5] branch: add --recurse-submodules option for branch creation Glen Choo
2021-12-11 18:08       ` Philippe Blain
2021-12-14 20:08         ` Glen Choo
2021-12-09 18:49     ` [PATCH v3 5/5] branch.c: replace questionable exit() codes Glen Choo
2021-12-10  2:21       ` Ævar Arnfjörð Bjarmason
2021-12-10 17:43         ` Glen Choo
2021-12-13  9:02         ` Junio C Hamano
2021-12-13  9:19           ` Ævar Arnfjörð Bjarmason
2021-12-13 19:26             ` Junio C Hamano
2021-12-09 21:59     ` [PATCH v3 0/5] implement branch --recurse-submodules Jonathan Tan
2021-12-09 22:21       ` Glen Choo
2021-12-13 23:20         ` Jonathan Tan
2021-12-14 18:47           ` Glen Choo
2021-12-16  0:32     ` [PATCH v4 " Glen Choo
2021-12-16  0:32       ` [PATCH v4 1/5] branch: move --set-upstream-to behavior to dwim_and_setup_tracking() Glen Choo
2021-12-16  0:32       ` [PATCH v4 2/5] branch: make create_branch() always create a branch Glen Choo
2021-12-16  0:32       ` [PATCH v4 3/5] branch: add a dry_run parameter to create_branch() Glen Choo
2021-12-16  0:32       ` [PATCH v4 4/5] builtin/branch: clean up action-picking logic in cmd_branch() Glen Choo
2021-12-16  0:32       ` [PATCH v4 5/5] branch: add --recurse-submodules option for branch creation Glen Choo
2021-12-16 23:33       ` [PATCH v5 0/5] implement branch --recurse-submodules Glen Choo
2021-12-16 23:33         ` [PATCH v5 1/5] branch: move --set-upstream-to behavior to dwim_and_setup_tracking() Glen Choo
2021-12-16 23:33         ` [PATCH v5 2/5] branch: make create_branch() always create a branch Glen Choo
2021-12-16 23:33         ` [PATCH v5 3/5] branch: add a dry_run parameter to create_branch() Glen Choo
2021-12-16 23:33         ` [PATCH v5 4/5] builtin/branch: clean up action-picking logic in cmd_branch() Glen Choo
2021-12-16 23:33         ` [PATCH v5 5/5] branch: add --recurse-submodules option for branch creation Glen Choo
2021-12-17  0:34         ` [PATCH v5 0/5] implement branch --recurse-submodules Junio C Hamano
2021-12-17  0:45           ` Junio C Hamano
2021-12-20 19:09             ` Glen Choo
2021-12-20 19:50               ` Junio C Hamano
2021-12-20 20:25                 ` Glen Choo
2021-12-20 23:34         ` [PATCH v6 " Glen Choo
2021-12-20 23:34           ` [PATCH v6 1/5] branch: move --set-upstream-to behavior to dwim_and_setup_tracking() Glen Choo
2022-01-11  2:09             ` Jonathan Tan
2022-01-11 17:29               ` Glen Choo
2022-01-11 20:03                 ` Jonathan Tan
2021-12-20 23:34           ` [PATCH v6 2/5] branch: make create_branch() always create a branch Glen Choo
2022-01-11  2:19             ` Jonathan Tan
2022-01-11 17:51               ` Glen Choo
2021-12-20 23:34           ` [PATCH v6 3/5] branch: add a dry_run parameter to create_branch() Glen Choo
2021-12-20 23:34           ` [PATCH v6 4/5] builtin/branch: clean up action-picking logic in cmd_branch() Glen Choo
2021-12-20 23:34           ` [PATCH v6 5/5] branch: add --recurse-submodules option for branch creation Glen Choo
2021-12-26  4:09             ` Junio C Hamano
2022-01-11  3:28             ` Jonathan Tan
2022-01-11 18:11               ` Glen Choo [this message]
2022-01-11 20:15                 ` Jonathan Tan
2022-01-11 23:22                   ` Glen Choo
2021-12-20 23:36           ` [PATCH v6 0/5] implement branch --recurse-submodules Glen Choo
2021-12-21  1:07           ` Junio C Hamano
2021-12-21 17:51             ` Glen Choo
2022-01-24 20:44           ` [PATCH v7 0/6] " Glen Choo
2022-01-24 20:44             ` [PATCH v7 1/6] branch: move --set-upstream-to behavior to dwim_and_setup_tracking() Glen Choo
2022-01-24 20:44             ` [PATCH v7 2/6] branch: make create_branch() always create a branch Glen Choo
2022-01-24 20:44             ` [PATCH v7 3/6] branch: add a dry_run parameter to create_branch() Glen Choo
2022-01-24 20:44             ` [PATCH v7 4/6] builtin/branch: consolidate action-picking logic in cmd_branch() Glen Choo
2022-01-24 20:44             ` [PATCH v7 5/6] branch: add --recurse-submodules option for branch creation Glen Choo
2022-01-27 20:29               ` Jonathan Tan
2022-01-27 21:32                 ` Glen Choo
2022-01-27 22:42                   ` Glen Choo
2022-01-24 20:44             ` [PATCH v7 6/6] branch.c: use 'goto cleanup' in setup_tracking() to fix memory leaks Glen Choo
2022-01-27 22:15               ` Junio C Hamano
2022-01-28 19:44                 ` Glen Choo
2022-01-29  0:04             ` [PATCH v8 0/6] implement branch --recurse-submodules Glen Choo
2022-01-29  0:04               ` [PATCH v8 1/6] branch: move --set-upstream-to behavior to dwim_and_setup_tracking() Glen Choo
2022-01-29  0:04               ` [PATCH v8 2/6] branch: make create_branch() always create a branch Glen Choo
2022-02-01 22:20                 ` Junio C Hamano
2022-01-29  0:04               ` [PATCH v8 3/6] branch: add a dry_run parameter to create_branch() Glen Choo
2022-01-29  0:04               ` [PATCH v8 4/6] builtin/branch: consolidate action-picking logic in cmd_branch() Glen Choo
2022-01-29  0:04               ` [PATCH v8 5/6] branch: add --recurse-submodules option for branch creation Glen Choo
2022-02-04  1:10                 ` Glen Choo
2022-02-04 16:15                   ` Junio C Hamano
2022-02-04 18:10                     ` Glen Choo
2022-01-29  0:04               ` [PATCH v8 6/6] branch.c: use 'goto cleanup' in setup_tracking() to fix memory leaks Glen Choo
2022-02-01 17:43               ` [PATCH v8 0/6] implement branch --recurse-submodules Jonathan Tan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=kl6l4k6akurn.fsf@chooglen-macbookpro.roam.corp.google.com \
    --to=chooglen@google.com \
    --cc=avarab@gmail.com \
    --cc=emilyshaffer@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jonathantanmy@google.com \
    --cc=levraiphilippeblain@gmail.com \
    --cc=steadmon@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).