{"thread":{"id":"61041","subject":"[PATCH 0/1] rebase: teach `--exec` about `GIT_REBASE_BRANCH`","startedAt":"2024-03-03T20:04:04Z","lastAt":"2024-03-07T15:19:15Z","messageCount":5,"participants":["Kristoffer Haugsbakk","Junio C Hamano","Phillip Wood"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"489821","messageId":"cover.1709495964.git.code@khaugsbakk.name","threadId":"61041","inReplyTo":null,"subject":"[PATCH 0/1] rebase: teach `--exec` about `GIT_REBASE_BRANCH`","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2024-03-03T20:03:36Z","receivedAt":"2024-03-03T20:04:04Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"The following patch adds an env. variable for the branch name that we\nwere on before the rebase operation started. This is for use by `--exec\n<cmd>`.\n\nThe need for fetching the branch name came up while making a script for\n`--exec` and it seemed that parsing the name out of the first line of\n`git branch --list` was the best approach.\n\nI thought that was inconvenient. Why not an environment variable set by\ngit-rebase(1)? (open question)\n\nSee: https://stackoverflow.com/a/50124157/1725151\n\n§ Implementation\n\nThe implementation is inspired by\n`builtin/branch.c:print_current_branch_name`.\n\nKristoffer Haugsbakk (1):\n  rebase: teach `--exec` about `GIT_REBASE_BRANCH`\n\n Documentation/git-rebase.txt |  4 ++++\n builtin/rebase.c             | 15 ++++++++++++++-\n t/t3409-rebase-environ.sh    | 19 +++++++++++++++++++\n 3 files changed, 37 insertions(+), 1 deletion(-)\n\n-- \n2.44.0.64.g52b67adbeb2\n\n"},{"id":"489822","messageId":"4140fca4f454310d215df8bdac237caeb5c38521.1709495964.git.code@khaugsbakk.name","threadId":"61041","inReplyTo":"cover.1709495964.git.code@khaugsbakk.name","subject":"[PATCH 1/1] rebase: teach `--exec` about `GIT_REBASE_BRANCH`","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2024-03-03T20:03:37Z","receivedAt":"2024-03-03T20:04:06Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"The command fed to `--exec` might need some contextual information from\nthe branch name. But there is no convenient access to the branch name\nthat we were on before starting the rebase; rebase operates in detached\nHEAD mode so we cannot ask for it directly. This means that we need to\nparse something like this from the first line of `git branch --list`:\n\n    (no branch, rebasing <branch>)\n\nThis is a moderate amount of effort for something that git-rebase(1) can\nstore for us.\n\nTo that end, teach `--exec` about an env. variable which stores the\nbranch name for the rebase-in-progress, if applicable.\n\nSigned-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n---\n Documentation/git-rebase.txt |  4 ++++\n builtin/rebase.c             | 15 ++++++++++++++-\n t/t3409-rebase-environ.sh    | 19 +++++++++++++++++++\n 3 files changed, 37 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 06206521fc3..9b3d6ee8203 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -578,6 +578,10 @@ squash/fixup series.\n This uses the `--interactive` machinery internally, but it can be run\n without an explicit `--interactive`.\n +\n+The command has access to the environment variable `GIT_REBASE_BRANCH`\n+which stores the branch name that `HEAD` was pointing at when the rebase\n+started, if applicable.\n++\n See also INCOMPATIBLE OPTIONS below.\n \n --root::\ndiff --git a/builtin/rebase.c b/builtin/rebase.c\nindex 5b086f651a6..0202130c2d7 100644\n--- a/builtin/rebase.c\n+++ b/builtin/rebase.c\n@@ -1044,6 +1044,17 @@ static int check_exec_cmd(const char *cmd)\n \treturn 0;\n }\n \n+static void try_set_env_git_rebase_branch(void)\n+{\n+\tconst char *refname = resolve_ref_unsafe(\"HEAD\", 0, NULL, NULL);\n+\tconst char *shortname = NULL;\n+\n+\tif (refname)\n+\t\tskip_prefix(refname, \"refs/heads/\", &shortname);\n+\tif (shortname)\n+\t\txsetenv(\"GIT_REBASE_BRANCH\", shortname, true);\n+}\n+\n int cmd_rebase(int argc, const char **argv, const char *prefix)\n {\n \tstruct rebase_options options = REBASE_OPTIONS_INIT;\n@@ -1451,8 +1462,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)\n \tif (gpg_sign)\n \t\toptions.gpg_sign_opt = xstrfmt(\"-S%s\", gpg_sign);\n \n-\tif (options.exec.nr)\n+\tif (options.exec.nr) {\n \t\timply_merge(&options, \"--exec\");\n+\t\ttry_set_env_git_rebase_branch();\n+\t}\n \n \tif (options.type == REBASE_APPLY) {\n \t\tif (ignore_whitespace)\ndiff --git a/t/t3409-rebase-environ.sh b/t/t3409-rebase-environ.sh\nindex acaf5558dbe..5b1d78a255a 100755\n--- a/t/t3409-rebase-environ.sh\n+++ b/t/t3409-rebase-environ.sh\n@@ -21,4 +21,23 @@ test_expect_success 'rebase --exec does not muck with GIT_WORK_TREE' '\n \ttest_must_be_empty environ\n '\n \n+test_expect_success 'rebase --exec cmd can access GIT_REBASE_BRANCH' '\n+\twrite_script cmd <<-\\EOF &&\n+printf \"%s\\n\" $GIT_REBASE_BRANCH >actual\n+EOF\n+\tgit branch --show-current >expect &&\n+\tgit rebase --exec ./cmd HEAD~1 &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'rebase --exec cmd has no GIT_REBASE_BRANCH when on detached HEAD' '\n+\ttest_when_finished git checkout - &&\n+\tgit checkout --detach &&\n+\twrite_script cmd <<-\\EOF &&\n+printf \"%s\" $GIT_REBASE_BRANCH >environ\n+EOF\n+\tgit rebase --exec ./cmd HEAD~1 &&\n+\ttest_must_be_empty environ\n+'\n+\n test_done\n-- \n2.44.0.64.g52b67adbeb2\n\n"},{"id":"489829","messageId":"xmqqo7buuce7.fsf@gitster.g","threadId":"61041","inReplyTo":"4140fca4f454310d215df8bdac237caeb5c38521.1709495964.git.code@khaugsbakk.name","subject":"Re: [PATCH 1/1] rebase: teach `--exec` about `GIT_REBASE_BRANCH`","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-03-03T23:24:48Z","receivedAt":"2024-03-03T23:24:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Kristoffer Haugsbakk <code@khaugsbakk.name> writes:\n\n> The command fed to `--exec` might need some contextual information from\n> the branch name. But there is no convenient access to the branch name\n> that we were on before starting the rebase; rebase operates in detached\n> HEAD mode so we cannot ask for it directly. This means that we need to\n> parse something like this from the first line of `git branch --list`:\n>\n>     (no branch, rebasing <branch>)\n>\n> This is a moderate amount of effort for something that git-rebase(1) can\n> store for us.\n>\n> To that end, teach `--exec` about an env. variable which stores the\n> branch name for the rebase-in-progress, if applicable.\n\nYou seem to be saying that `git branch --list` output already\ncontains the necessary information but it is shown in a hard to use\nformat.  Is the information given at least always accurate and\nreliable?\n\nAssuming it is, do you know where \"git branch --list\" gets that\ninformation when it says \"(no branch, rebasing <branch>)\"?\n\ngit-rebase(1) is already storing information sufficient to let \"git\nbranch --list\" to produce that information, and there are other ways\nto inspect that state (\"git status\" gives the same information but\nit also is in a \"meant for humans\" format).\n\nSo, isn't it just the matter of surfacing the information that we\nare already recording and is already available in a fashion that is\neasier to use?  For example, if \"git status --porcelain=[version]\"\ndoes not give the information, perhaps you can add a line or two to\nit, instead of duplicating the same information in two places?\n\nIt comes from wt-status.c:wt_status_check_rebase() where state->branch\nis assigned to, by reading \"$GIT_DIR/rebase-{apply,merge}/head-name\".\n\n\n"},{"id":"489859","messageId":"6d7d6be1-6d3f-49a0-baca-2a05b8507e12@gmail.com","threadId":"61041","inReplyTo":"xmqqo7buuce7.fsf@gitster.g","subject":"Re: [PATCH 1/1] rebase: teach `--exec` about `GIT_REBASE_BRANCH`","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-03-04T09:56:08Z","receivedAt":"2024-03-04T09:56:10Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 03/03/2024 23:24, Junio C Hamano wrote:\n> Kristoffer Haugsbakk <code@khaugsbakk.name> writes:\n> \n> So, isn't it just the matter of surfacing the information that we\n> are already recording and is already available in a fashion that is\n> easier to use?  For example, if \"git status --porcelain=[version]\"\n> does not give the information, perhaps you can add a line or two to\n> it, instead of duplicating the same information in two places?\n\nThat was my thought as well. I also don't think it is helpful to think \nof a single branch being associated with a rebase these days. If we \nupdate the output of \"git stasus --porcelain\" we should show all the \nrefs that are being rewritten by reading the contents of \nrebase_path_update_refs() as well as the head-name file.\n\nBest Wishes\n\nPhillip\n"},{"id":"490186","messageId":"b2555c2c-0725-4d33-853b-e17022689977@app.fastmail.com","threadId":"61041","inReplyTo":"xmqqo7buuce7.fsf@gitster.g","subject":"Re: [PATCH 1/1] rebase: teach `--exec` about `GIT_REBASE_BRANCH`","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2024-03-07T15:18:52Z","receivedAt":"2024-03-07T15:19:15Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"On Mon, Mar 4, 2024, at 00:24, Junio C Hamano wrote:\n> Kristoffer Haugsbakk <code@khaugsbakk.name> writes:\n>\n>> The command fed to `--exec` might need some contextual information from\n>> the branch name. But there is no convenient access to the branch name\n>> that we were on before starting the rebase; rebase operates in detached\n>> HEAD mode so we cannot ask for it directly. This means that we need to\n>> parse something like this from the first line of `git branch --list`:\n>>\n>>     (no branch, rebasing <branch>)\n>>\n>> This is a moderate amount of effort for something that git-rebase(1) can\n>> store for us.\n>>\n>> To that end, teach `--exec` about an env. variable which stores the\n>> branch name for the rebase-in-progress, if applicable.\n>\n> You seem to be saying that `git branch --list` output already\n> contains the necessary information but it is shown in a hard to use\n> format.  Is the information given at least always accurate and\n> reliable?\n>\n> Assuming it is, do you know where \"git branch --list\" gets that\n> information when it says \"(no branch, rebasing <branch>)\"?\n>\n> git-rebase(1) is already storing information sufficient to let \"git\n> branch --list\" to produce that information, and there are other ways\n> to inspect that state (\"git status\" gives the same information but\n> it also is in a \"meant for humans\" format).\n>\n> So, isn't it just the matter of surfacing the information that we\n> are already recording and is already available in a fashion that is\n> easier to use?  For example, if \"git status --porcelain=[version]\"\n> does not give the information, perhaps you can add a line or two to\n> it, instead of duplicating the same information in two places?\n>\n> It comes from wt-status.c:wt_status_check_rebase() where state->branch\n> is assigned to, by reading \"$GIT_DIR/rebase-{apply,merge}/head-name\".\n\nOkay, thanks for the code directions and input (both). I’ll try to get\nback to a rewrite on this topic in a while.\n\nCheers\n\n-- \nKristoffer Haugsbakk\n"}]}