From: Glen Choo <chooglen@google.com>
To: git@vger.kernel.org
Cc: "Glen Choo" <chooglen@google.com>,
"Jonathan Tan" <jonathantanmy@google.com>,
"Josh Steadmon" <steadmon@google.com>,
"Emily Shaffer" <emilyshaffer@google.com>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Philippe Blain" <levraiphilippeblain@gmail.com>,
"Junio C Hamano" <gitster@pobox.com>
Subject: [PATCH v4 0/5] implement branch --recurse-submodules
Date: Wed, 15 Dec 2021 16:32:08 -0800 [thread overview]
Message-ID: <20211216003213.99135-1-chooglen@google.com> (raw)
In-Reply-To: <20211209184928.71413-1-chooglen@google.com>
Submodule branching RFC:
https://lore.kernel.org/git/kl6lv912uvjv.fsf@chooglen-macbookpro.roam.corp.google.com/
Original Submodule UX RFC/Discussion:
https://lore.kernel.org/git/YHofmWcIAidkvJiD@google.com/
Contributor Summit submodules Notes:
https://lore.kernel.org/git/nycvar.QRO.7.76.6.2110211148060.56@tvgsbejvaqbjf.bet/
Submodule UX overhaul updates:
https://lore.kernel.org/git/?q=Submodule+UX+overhaul+update
This series implements branch --recurse-submodules as laid out in the
Submodule branching RFC (linked above). If there are concerns about the
UX/behavior, I would appreciate feedback on the RFC thread as well :)
This series is based off js/branch-track-inherit.
Future work:
* `git branch -d --recurse-submodules` so that users can clean up
extraneous branches.
* `git [checkout | switch] --recurse-submodules` +
submodule.propagateBranches so that users can actually checkout the
branches.
* After [1], it seems clear that --recurse-submodules parsing could
really benefit from some standardization. It's not obvious which
RECURSE_SUBMODULE_* enums are applicable to which commands, and there
is no way to distinguish between an explicit --recurse-submodules from
argv vs submodule.recurse from the config.
I chose not to use them in this series because their usage is already
inconsistent (grep.c doesn't use them either), and it would be _more_
confusing to use the enum (handling RECURSE_SUBMODULES_DEFAULT = 1 is
trickier than boolean 0 and 1).
At this point, I think it would be too noisy to introduce the enum,
but this would be a nice cleanup to do later.
* As documented in branch.c, we create branches using a child process
only because install_branch_config() does not support submodules.
It should be possible to remove the child process once we make the
appropriate changes to config.c. I attempted this in [2] but chose to
punt it because it was too time-consuming at the time.
Changes since v3:
* Split up the old patch 1. Patch 1 had a big diff because it used to
move lines, remove dead code and introduce repo_* functions (thanks
Jonathan!)
** repo_* functions have been dropped; they added noise and are not
necessary for correctness.
* Use a new, harder-to-misuse function in --set-upstream-to,
dwim_and_setup_tracking(). Now, setup_tracking() never does DWIM and
dwim_and_setup_tracking() always does DWIM.
* Move create_branch() dry_run to its own patch.
* Fix an oversight where submodules in subtrees were ignored. This was
because submodules_of_tree() and tree_entry() didn't recurse into
subtrees. Test this accordingly (thanks Jonathan!).
* cmd_branch() possible actions are more consistently ordered.
* Documentation fixes (thanks Philippe!).
* Additional comments and explanation.
* Drop patch 5 (optional cleanup).
* Rebase onto js/branch-track-inherit v6.
Changes since v2:
* Rebase onto js/branch-track-inherit. This series should continue to be
the case going forward.
* Patch 1 has a smaller diff because the introduction of
validate_branch_start() no longer changes the function order thanks to a
forward declaration. This artificial forward declaration is removed in a
patch 2 (which can just be squashed into patch 1).
* Optional cleanup: fix questionable exit codes in patch 5.
Changes since v1:
* Move the functionality of "git branch --dry-run" into "git submodule-helper create-branch --dry-run"
* Add more fields to the submodules_of_tree() struct to reduce the
number of allocations made by the caller. Move this functionality
to patch 3 (formerly patch 4) and drop patch 1.
* Make submodules_of_tree() ignore inactive submodules
* Structure the output of the submodules a bit better by adding prefixes
to the child process' output (instead of inconsistently indenting the
output).
** I wasn't able to find a good way to interleave stdout/stderr
correctly, so a less-than-desirable workaround was to route the child
process output to stdout/stderr depending on the exit code.
** Eventually, I would like to structure the output of submodules in a
report, as Ævar suggested. But at this stage, I think that it's
better to spend time getting user feedback on the submodules
branching UX and it'll be easier to standardize the output when we've
implemented more of the UX :)
[1] https://lore.kernel.org/git/kl6lbl1p9zjf.fsf@chooglen-macbookpro.roam.corp.google.com/
[2] https://lore.kernel.org/git/kl6lv90ytd4v.fsf@chooglen-macbookpro.roam.corp.google.com/
Glen Choo (5):
branch: move --set-upstream-to behavior to dwim_and_setup_tracking()
branch: make create_branch() always create a branch
branch: add a dry_run parameter to create_branch()
builtin/branch: clean up action-picking logic in cmd_branch()
branch: add --recurse-submodules option for branch creation
Documentation/config/advice.txt | 3 +
Documentation/config/submodule.txt | 24 ++-
Documentation/git-branch.txt | 11 +-
advice.c | 1 +
advice.h | 1 +
branch.c | 257 ++++++++++++++++++++-----
branch.h | 57 +++++-
builtin/branch.c | 70 +++++--
builtin/checkout.c | 3 +-
builtin/submodule--helper.c | 38 ++++
submodule-config.c | 60 ++++++
submodule-config.h | 34 ++++
submodule.c | 11 +-
submodule.h | 3 +
t/t3200-branch.sh | 17 ++
t/t3207-branch-submodule.sh | 291 +++++++++++++++++++++++++++++
16 files changed, 805 insertions(+), 76 deletions(-)
create mode 100755 t/t3207-branch-submodule.sh
Range-diff against v3:
1: 8241c0b51a < -: ---------- branch: move --set-upstream-to behavior to setup_tracking()
2: b74bcbaade < -: ---------- branch: remove forward declaration of validate_branch_start()
-: ---------- > 1: dfdbbaaca5 branch: move --set-upstream-to behavior to dwim_and_setup_tracking()
-: ---------- > 2: e22a177cb7 branch: make create_branch() always create a branch
-: ---------- > 3: 8a895aa401 branch: add a dry_run parameter to create_branch()
3: 235173efc9 ! 4: 971c53ec85 builtin/branch: clean up action-picking logic in cmd_branch()
@@ Commit message
Such an option does not exist yet, but one will be introduced in a
subsequent commit.
- Incidentally, fix an incorrect usage string that combined the 'list'
- usage of git branch (-l) with the 'create' usage; this string has been
- incorrect since its inception, a8dfd5eac4 (Make builtin-branch.c use
- parse_options., 2007-10-07).
-
Signed-off-by: Glen Choo <chooglen@google.com>
## builtin/branch.c ##
-@@
-
- static const char * const builtin_branch_usage[] = {
- N_("git branch [<options>] [-r | -a] [--merged] [--no-merged]"),
-- N_("git branch [<options>] [-l] [-f] <branch-name> [<start-point>]"),
-+ N_("git branch [<options>] [-l] [<pattern>...]"),
- N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
- N_("git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"),
- N_("git branch [<options>] (-c | -C) [<old-branch>] <new-branch>"),
@@ builtin/branch.c: static int edit_branch_description(const char *branch_name)
int cmd_branch(int argc, const char **argv, const char *prefix)
@@ builtin/branch.c: static int edit_branch_description(const char *branch_name)
- int reflog = 0, edit_description = 0;
- int quiet = 0, unset_upstream = 0;
+ /* possible actions */
-+ int delete = 0, rename = 0, copy = 0, force = 0, list = 0,
++ int delete = 0, rename = 0, copy = 0, list = 0,
+ unset_upstream = 0, show_current = 0, edit_description = 0;
+ const char *new_upstream = NULL;
+ int noncreate_actions = 0;
+ /* possible options */
-+ int reflog = 0, quiet = 0, icase = 0;
- const char *new_upstream = NULL;
++ int reflog = 0, quiet = 0, icase = 0, force = 0;
enum branch_track track;
struct ref_filter filter;
- int icase = 0;
4: 3dabb8e2fa ! 5: cd88f3ad92 branch: add --recurse-submodules option for branch creation
@@ Commit message
* add the "submoduleNotUpdated" advice to advise users to update the
submodules in their trees
- Other changes
-
- * add a "dry_run" parameter to create_branch() in order to support
- `git submodule--helper create-branch --dry-run`
+ Incidentally, fix an incorrect usage string that combined the 'list'
+ usage of git branch (-l) with the 'create' usage; this string has been
+ incorrect since its inception, a8dfd5eac4 (Make builtin-branch.c use
+ parse_options., 2007-10-07).
Signed-off-by: Glen Choo <chooglen@google.com>
@@ Documentation/config/advice.txt: advice.*::
configured to "die" causes a fatal error.
+ submodulesNotUpdated::
+ Advice shown when a user runs a submodule command that fails
-+ because `git submodule update` was not run.
++ because `git submodule update --init` was not run.
addIgnoredFile::
Advice shown if a user attempts to add an ignored file to
the index.
## Documentation/config/submodule.txt ##
+@@ Documentation/config/submodule.txt: submodule.active::
+
+ submodule.recurse::
+ A boolean indicating if commands should enable the `--recurse-submodules`
+- option by default.
+- Applies to all commands that support this option
+- (`checkout`, `fetch`, `grep`, `pull`, `push`, `read-tree`, `reset`,
+- `restore` and `switch`) except `clone` and `ls-files`.
+- Defaults to false.
++ option by default. Defaults to false.
++ +
+ When set to true, it can be deactivated via the
+ `--no-recurse-submodules` option. Note that some Git commands
+ lacking this option may call some of the above commands affected by
@@ Documentation/config/submodule.txt: 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
++
+submodule.propagateBranches::
+ [EXPERIMENTAL] A boolean that enables branching support when
+ using `--recurse-submodules` or `submodule.recurse=true`.
@@ Documentation/config/submodule.txt: submodule.recurse::
+ `--recurse-submodules` and certain commands that already accept
+ `--recurse-submodules` will now consider branches.
+ Defaults to false.
-+
+
submodule.fetchJobs::
Specifies how many submodules are fetched/cloned at the same time.
- A positive integer allows up to that number of submodules fetched
+
+ ## Documentation/git-branch.txt ##
+@@ Documentation/git-branch.txt: SYNOPSIS
+ [--points-at <object>] [--format=<format>]
+ [(-r | --remotes) | (-a | --all)]
+ [--list] [<pattern>...]
+-'git branch' [--track [direct|inherit] | --no-track] [-f] <branchname> [<start-point>]
++'git branch' [--track [direct|inherit] | --no-track] [-f]
++ [--recurse-submodules] <branchname> [<start-point>]
+ 'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
+ 'git branch' --unset-upstream [<branchname>]
+ 'git branch' (-m | -M) [<oldbranch>] <newbranch>
+@@ Documentation/git-branch.txt: how the `branch.<name>.remote` and `branch.<name>.merge` options are used.
+ Do not set up "upstream" configuration, even if the
+ branch.autoSetupMerge configuration variable is set.
+
++--recurse-submodules::
++ THIS OPTION IS EXPERIMENTAL! Causes the current command to
++ recurse into submodules if `submodule.propagateBranches` is
++ enabled. See `submodule.propagateBranches` in
++ linkgit:git-config[1].
++ +
++ Currently, only branch creation is supported.
++
+ --set-upstream::
+ As this option had confusing syntax, it is no longer supported.
+ Please use `--track` or `--set-upstream-to` instead.
## advice.c ##
@@ advice.c: static struct {
@@ branch.c
struct tracking {
struct refspec_item spec;
-@@ branch.c: void setup_tracking(const char *new_ref, const char *orig_ref,
-
- void create_branch(struct repository *r, const char *name,
- const char *start_name, int force, int clobber_head_ok,
-- int reflog, int quiet, enum branch_track track)
-+ int reflog, int quiet, enum branch_track track, int dry_run)
- {
- struct object_id oid;
- char *real_ref;
-@@ branch.c: void create_branch(struct repository *r, const char *name,
- }
-
- validate_branch_start(r, start_name, track, &oid, &real_ref);
-+ if (dry_run)
-+ goto cleanup;
-
- if (reflog)
- log_all_ref_updates = LOG_REFS_NORMAL;
-@@ branch.c: void create_branch(struct repository *r, const char *name,
- if (real_ref && track)
- setup_tracking(ref.buf + 11, real_ref, track, quiet, 0);
-
-+cleanup:
- strbuf_release(&ref);
- free(real_ref);
+@@ branch.c: 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.
++ */
+static int submodule_create_branch(struct repository *r,
+ const struct submodule *submodule,
+ const char *name, const char *start_oid,
@@ branch.c: void create_branch(struct repository *r, const char *name,
+ struct submodule_entry_list submodule_entry_list;
+
+ /* Perform dwim on start_name to get super_oid and branch_point. */
-+ validate_branch_start(r, start_name, BRANCH_TRACK_NEVER, &super_oid,
-+ &branch_point);
++ dwim_branch_start(r, start_name, BRANCH_TRACK_NEVER, &branch_point,
++ &super_oid);
+
+ /*
+ * If we were not given an explicit name to track, then assume we are at
@@ branch.c: void create_branch(struct repository *r, const char *name,
+ * tedious to determine whether or not tracking was set up in the
+ * superproject.
+ */
-+ setup_tracking(name, tracking_name, track, quiet, 0);
++ setup_tracking(name, tracking_name, track, quiet);
+
+ for (i = 0; i < submodule_entry_list.entry_nr; i++) {
+ if (submodule_create_branch(
@@ branch.c: void create_branch(struct repository *r, const char *name,
unlink(git_path_merge_head(r));
## branch.h ##
-@@ branch.h: void setup_tracking(const char *new_ref, const char *orig_ref,
- * - track causes the new branch to be configured to merge the remote branch
- * that start_name is a tracking branch for (if any).
- *
-+ * - dry_run causes the branch to be validated but not created.
-+ *
- */
--void create_branch(struct repository *r,
-- const char *name, const char *start_name,
-- int force, int clobber_head_ok,
-- int reflog, int quiet, enum branch_track track);
-+void create_branch(struct repository *r, const char *name,
-+ const char *start_name, int force, int clobber_head_ok,
-+ int reflog, int quiet, enum branch_track track, int dry_run);
+@@ branch.h: void create_branch(struct repository *r, const char *name,
+ const char *start_name, int force, int clobber_head_ok,
+ int reflog, int quiet, enum branch_track track, int dry_run);
+/*
+ * Creates a new branch in repository and its submodules (and its
@@ branch.h: void setup_tracking(const char *new_ref, const char *orig_ref,
* Return 1 if the named branch already exists; return 0 otherwise.
## builtin/branch.c ##
+@@
+
+ static const char * const builtin_branch_usage[] = {
+ N_("git branch [<options>] [-r | -a] [--merged] [--no-merged]"),
+- N_("git branch [<options>] [-l] [-f] <branch-name> [<start-point>]"),
++ N_("git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-point>]"),
++ N_("git branch [<options>] [-l] [<pattern>...]"),
+ N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
+ N_("git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"),
+ N_("git branch [<options>] (-c | -C) [<old-branch>] <new-branch>"),
@@ builtin/branch.c: static const char * const builtin_branch_usage[] = {
static const char *head;
@@ builtin/branch.c: static int git_branch_config(const char *var, const char *valu
}
@@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix)
- unset_upstream = 0, show_current = 0, edit_description = 0;
+ const char *new_upstream = NULL;
int noncreate_actions = 0;
/* possible options */
-- int reflog = 0, quiet = 0, icase = 0;
-+ int reflog = 0, quiet = 0, icase = 0, recurse_submodules_explicit = 0;
- const char *new_upstream = NULL;
+- int reflog = 0, quiet = 0, icase = 0, force = 0;
++ int reflog = 0, quiet = 0, icase = 0, force = 0,
++ recurse_submodules_explicit = 0;
enum branch_track track;
struct ref_filter filter;
+ static struct ref_sorting *sorting;
@@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_CALLBACK(0, "points-at", &filter.points_at, N_("object"),
N_("print only branches of the object"), parse_opt_object_name),
@@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix
- create_branch(the_repository,
- argv[0], (argc == 2) ? argv[1] : head,
-- force, 0, reflog, quiet, track);
+- force, 0, reflog, quiet, track, 0);
-
+ if (recurse_submodules) {
+ create_branches_recursively(the_repository, branch_name,
@@ builtin/branch.c: int cmd_branch(int argc, const char **argv, const char *prefix
usage_with_options(builtin_branch_usage, options);
- ## builtin/checkout.c ##
-@@ builtin/checkout.c: static void update_refs_for_switch(const struct checkout_opts *opts,
- opts->new_branch_force ? 1 : 0,
- opts->new_branch_log,
- opts->quiet,
-- opts->track);
-+ opts->track,
-+ 0);
- new_branch_info->name = opts->new_branch;
- setup_branch_path(new_branch_info);
- }
-
## builtin/submodule--helper.c ##
@@
#include "diff.h"
@@ submodule-config.c: const struct submodule *submodule_from_path(struct repositor
return config_from(r->submodule_cache, treeish_name, path, lookup_path);
}
-+void submodules_of_tree(struct repository *r,
-+ const struct object_id *treeish_name,
-+ struct submodule_entry_list *out)
++/**
++ * Used internally by submodules_of_tree(). Recurses into 'treeish_name'
++ * and appends submodule entries to 'out'. The submodule_cache expects
++ * a root-level treeish_name and paths, so keep track of these values
++ * with 'root_tree' and 'prefix'.
++ */
++static void traverse_tree_submodules(struct repository *r,
++ const struct object_id *root_tree,
++ char *prefix,
++ const struct object_id *treeish_name,
++ struct submodule_entry_list *out)
+{
+ struct tree_desc tree;
+ struct submodule_tree_entry *st_entry;
+ struct name_entry *name_entry;
++ char *tree_path = NULL;
+
+ name_entry = xmalloc(sizeof(*name_entry));
+
++ fill_tree_descriptor(r, &tree, treeish_name);
++ while (tree_entry(&tree, name_entry)) {
++ if (prefix)
++ tree_path =
++ mkpathdup("%s/%s", prefix, name_entry->path);
++ else
++ tree_path = xstrdup(name_entry->path);
++
++ if (S_ISGITLINK(name_entry->mode) &&
++ is_tree_submodule_active(r, root_tree, tree_path)) {
++ st_entry = xmalloc(sizeof(*st_entry));
++ st_entry->name_entry = name_entry;
++ st_entry->submodule =
++ submodule_from_path(r, root_tree, tree_path);
++ st_entry->repo = xmalloc(sizeof(*st_entry->repo));
++ if (repo_submodule_init(st_entry->repo, r, tree_path,
++ root_tree))
++ FREE_AND_NULL(st_entry->repo);
++
++ ALLOC_GROW(out->entries, out->entry_nr + 1,
++ out->entry_alloc);
++ out->entries[out->entry_nr++] = *st_entry;
++ } else if (S_ISDIR(name_entry->mode))
++ traverse_tree_submodules(r, root_tree, tree_path,
++ &name_entry->oid, out);
++ free(tree_path);
++ }
++}
++
++void submodules_of_tree(struct repository *r,
++ const struct object_id *treeish_name,
++ struct submodule_entry_list *out)
++{
+ CALLOC_ARRAY(out->entries, 0);
+ out->entry_nr = 0;
+ out->entry_alloc = 0;
+
-+ fill_tree_descriptor(r, &tree, treeish_name);
-+ while (tree_entry(&tree, name_entry)) {
-+ if (!S_ISGITLINK(name_entry->mode) || !is_tree_submodule_active(r, treeish_name, name_entry->path)) {
-+ continue;
-+ }
-+
-+ st_entry = xmalloc(sizeof(*st_entry));
-+ st_entry->name_entry = name_entry;
-+ st_entry->submodule =
-+ submodule_from_path(r, treeish_name, name_entry->path);
-+ st_entry->repo = xmalloc(sizeof(*st_entry->repo));
-+ if (repo_submodule_init(st_entry->repo, r, name_entry->path,
-+ treeish_name))
-+ FREE_AND_NULL(st_entry->repo);
-+
-+ ALLOC_GROW(out->entries, out->entry_nr + 1, out->entry_alloc);
-+ out->entries[out->entry_nr++] = *st_entry;
-+ }
++ traverse_tree_submodules(r, treeish_name, NULL, treeish_name, out);
+}
+
void submodule_free(struct repository *r)
@@ submodule-config.h: int check_submodule_name(const char *name);
+};
+
+/**
-+ * Given a treeish, return all submodules in the tree. This only reads
-+ * one level of the tree, so it will not return nested submodules;
-+ * callers that require nested submodules are expected to handle the
-+ * recursion themselves.
++ * Given a treeish, return all submodules in the tree and its subtrees,
++ * but excluding nested submodules. Callers that require nested
++ * submodules are expected to recurse into the submodules themselves.
+ */
+void submodules_of_tree(struct repository *r,
+ const struct object_id *treeish_name,
@@ t/t3207-branch-submodule.sh (new)
+ 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
@@ t/t3207-branch-submodule.sh (new)
+ git branch --recurse-submodules branch-a &&
+ git rev-parse branch-a &&
+ git -C sub rev-parse branch-a &&
-+ git -C sub/sub-sub rev-parse branch-a
++ git -C sub/sub-sub rev-parse branch-a &&
++ git -C second/sub rev-parse branch-a
+ )
+'
+
@@ t/t3207-branch-submodule.sh (new)
+ )
+'
+
-+test_expect_success 'should create branch when submodule is not in HEAD .gitmodules' '
++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 &&
@@ t/t3207-branch-submodule.sh (new)
+ 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 rev-parse branch-c &&
++ git -C sub2/sub-sub rev-parse branch-c
+ )
+'
+
5: 70fb03f882 < -: ---------- branch.c: replace questionable exit() codes
--
2.33.GIT
next prev parent reply other threads:[~2021-12-16 0:32 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 ` Glen Choo [this message]
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
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211216003213.99135-1-chooglen@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.
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 NNTP newsgroup(s).