From: Luiz Campos <luizedc1@gmail.com>
To: git@vger.kernel.org
Cc: luizedc1@gmail.com, peff@peff.net, sagotsky@gmail.com,
Johannes.Schindelin@gmx.de
Subject: [RFC PATCH 1/1] add -p: support discarding hunks with 'x'
Date: Wed, 25 Mar 2026 04:50:55 -0300 [thread overview]
Message-ID: <20260325075055.354709-2-luizedc1@gmail.com> (raw)
In-Reply-To: <20260325075055.354709-1-luizedc1@gmail.com>
When using `git add -p`, users can stage or skip hunks,
but cannot discard unwanted changes from the working tree.
Introduce a new 'x' action to discard the current hunk by
reverse-applying it.
This idea was suggested in a previous mailing list discussion:
https://lore.kernel.org/git/X%2FiFCo0bXLR%2BLZXs@coredump.intra.peff.net/t/#m0576e6f3c6375e11cc4693b9dca3c1fc57baadd0
Feedback is very welcome.
Signed-off-by: Luiz Campos <luizedc1@gmail.com>
---
Documentation/git-add.adoc | 7 +-
add-patch.c | 137 ++++++++++++++++++++++++++++---------
t/t3701-add-interactive.sh | 58 ++++++++++------
3 files changed, 149 insertions(+), 53 deletions(-)
diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc
index 941135dc63..0ab81e5615 100644
--- a/Documentation/git-add.adoc
+++ b/Documentation/git-add.adoc
@@ -351,12 +351,15 @@ patch::
K - go to the previous hunk, roll over at the top
s - split the current hunk into smaller hunks
e - manually edit the current hunk
+ x - discard this hunk from the worktree
p - print the current hunk
P - print the current hunk using the pager
? - print help
+
-After deciding the fate for all hunks, if there is any hunk
-that was chosen, the index is updated with the selected hunks.
+After deciding the fate for all hunks, any hunks marked for
+discard are removed from the working tree (reverted to the index
+version for those lines). Then, if there is any hunk chosen for
+staging, the index is updated with those hunks.
+
You can omit having to type return here, by setting the configuration
variable `interactive.singleKey` to `true`.
diff --git a/add-patch.c b/add-patch.c
index 4e28e5c187..ea38ab453e 100644
--- a/add-patch.c
+++ b/add-patch.c
@@ -259,7 +259,7 @@ struct hunk_header {
struct hunk {
size_t start, end, colored_start, colored_end, splittable_into;
ssize_t delta;
- enum { UNDECIDED_HUNK = 0, SKIP_HUNK, USE_HUNK } use;
+ enum { UNDECIDED_HUNK = 0, SKIP_HUNK, USE_HUNK, DISCARD_HUNK } use;
struct hunk_header header;
};
@@ -884,17 +884,35 @@ static void render_diff_header(struct add_p_state *s,
}
}
+static bool should_merge_hunk(struct file_diff *file_diff,
+ size_t hunk_index, int use_all,
+ int merge_for_discard)
+{
+ if (use_all)
+ return true;
+ return merge_for_discard
+ ? file_diff->hunk[hunk_index].use == DISCARD_HUNK
+ : file_diff->hunk[hunk_index].use == USE_HUNK;
+}
+
+enum reassemble_mode {
+ REASSEMBLE_STAGE,
+ REASSEMBLE_DISCARD
+};
+
/* Coalesce hunks again that were split */
static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
- size_t *hunk_index, int use_all, struct hunk *merged)
+ size_t *hunk_index, int use_all, struct hunk *merged,
+ int merge_for_discard)
{
size_t i = *hunk_index, delta;
struct hunk *hunk = file_diff->hunk + i;
/* `header` corresponds to the merged hunk */
struct hunk_header *header = &merged->header, *next;
- if (!use_all && hunk->use != USE_HUNK)
+ if (!should_merge_hunk(file_diff, *hunk_index, use_all, merge_for_discard)) {
return 0;
+ }
*merged = *hunk;
/* We simply skip the colored part (if any) when merging hunks */
@@ -907,10 +925,10 @@ static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
/*
* Stop merging hunks when:
*
- * - the hunk is not selected for use, or
+ * - the hunk is not selected for use (or discard, when merging discards), or
* - the hunk does not overlap with the already-merged hunk(s)
*/
- if ((!use_all && hunk->use != USE_HUNK) ||
+ if (!should_merge_hunk(file_diff, i + 1, use_all, merge_for_discard) ||
header->new_offset >= next->new_offset + merged->delta ||
header->new_offset + header->new_count
< next->new_offset + merged->delta)
@@ -1014,11 +1032,13 @@ static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,
static void reassemble_patch(struct add_p_state *s,
struct file_diff *file_diff, int use_all,
+ enum reassemble_mode mode,
struct strbuf *out)
{
struct hunk *hunk;
size_t save_len = s->plain.len, i;
ssize_t delta = 0;
+ int merge_for_discard = (mode == REASSEMBLE_DISCARD);
render_diff_header(s, file_diff, 0, out);
@@ -1026,25 +1046,26 @@ static void reassemble_patch(struct add_p_state *s,
struct hunk merged = { 0 };
hunk = file_diff->hunk + i;
- if (!use_all && hunk->use != USE_HUNK)
+ if (!should_merge_hunk(file_diff, i, use_all, merge_for_discard)) {
delta += hunk->header.old_count
- hunk->header.new_count;
- else {
- /* merge overlapping hunks into a temporary hunk */
- if (merge_hunks(s, file_diff, &i, use_all, &merged))
- hunk = &merged;
+ continue;
+ }
- render_hunk(s, hunk, delta, 0, out);
+ if (merge_hunks(s, file_diff, &i, use_all, &merged,
+ merge_for_discard))
+ hunk = &merged;
- /*
- * In case `merge_hunks()` used `plain` as a scratch
- * pad (this happens when an edited hunk had to be
- * coalesced with another hunk).
- */
- strbuf_setlen(&s->plain, save_len);
+ render_hunk(s, hunk, delta, 0, out);
- delta += hunk->delta;
- }
+ /*
+ * In case `merge_hunks()` used `plain` as a scratch
+ * pad (this happens when an edited hunk had to be
+ * coalesced with another hunk).
+ */
+ strbuf_setlen(&s->plain, save_len);
+
+ delta += hunk->delta;
}
}
@@ -1348,7 +1369,7 @@ static int run_apply_check(struct add_p_state *s,
struct child_process cp = CHILD_PROCESS_INIT;
strbuf_reset(&s->buf);
- reassemble_patch(s, file_diff, 1, &s->buf);
+ reassemble_patch(s, file_diff, 1, REASSEMBLE_STAGE, &s->buf);
setup_child_process(s, &cp,
"apply", "--check", NULL);
@@ -1522,7 +1543,8 @@ static size_t display_hunks(struct add_p_state *s,
strbuf_reset(&s->buf);
strbuf_addf(&s->buf, "%c%2d: ", hunk->use == USE_HUNK ? '+'
- : hunk->use == SKIP_HUNK ? '-' : ' ',
+ : hunk->use == SKIP_HUNK ? '-'
+ : hunk->use == DISCARD_HUNK ? 'x' : ' ',
(int)start_index);
summarize_hunk(s, hunk, &s->buf);
fputs(s->buf.buf, stdout);
@@ -1540,6 +1562,7 @@ N_("j - go to the next undecided hunk, roll over at the bottom\n"
"/ - search for a hunk matching the given regex\n"
"s - split the current hunk into smaller hunks\n"
"e - manually edit the current hunk\n"
+ "x - discard this hunk from the worktree\n"
"p - print the current hunk\n"
"P - print the current hunk using the pager\n"
"> - go to the next file, roll over at the bottom\n"
@@ -1547,21 +1570,57 @@ N_("j - go to the next undecided hunk, roll over at the bottom\n"
"? - print help\n"
"HUNKS SUMMARY - Hunks: %d, USE: %d, SKIP: %d\n");
+static int apply_discard_hunks(struct add_p_state *s,
+ struct file_diff *file_diff)
+{
+ struct child_process check_cp = CHILD_PROCESS_INIT;
+ struct child_process apply_cp = CHILD_PROCESS_INIT;
+
+ strbuf_reset(&s->buf);
+ reassemble_patch(s, file_diff, 0, REASSEMBLE_DISCARD, &s->buf);
+
+ discard_index(s->index);
+
+ setup_child_process(s, &check_cp, "apply", "-R", "--check", NULL);
+ if (pipe_command(&check_cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0)) {
+ error(_("'git apply -R --check' failed"));
+ return -1;
+ }
+
+ setup_child_process(s, &apply_cp, "apply", "-R", NULL);
+ if (pipe_command(&apply_cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0)) {
+ error(_("'git apply -R' failed"));
+ return -1;
+ }
+
+ return 0;
+}
+
static void apply_patch(struct add_p_state *s, struct file_diff *file_diff)
{
struct child_process cp = CHILD_PROCESS_INIT;
size_t j;
+ int needs_refresh = 0;
+
+ if (s->mode == &patch_mode_add) {
+ for (j = 0; j < file_diff->hunk_nr; j++) {
+ if (file_diff->hunk[j].use == DISCARD_HUNK)
+ break;
+ }
+ if (j < file_diff->hunk_nr && apply_discard_hunks(s, file_diff))
+ return;
+ if (j < file_diff->hunk_nr)
+ needs_refresh = 1;
+ }
- /* Any hunk to be used? */
for (j = 0; j < file_diff->hunk_nr; j++)
if (file_diff->hunk[j].use == USE_HUNK)
break;
if (j < file_diff->hunk_nr ||
- (!file_diff->hunk_nr && file_diff->head.use == USE_HUNK)) {
- /* At least one hunk selected: apply */
+ (!file_diff->hunk_nr && file_diff->head.use == USE_HUNK)) {
strbuf_reset(&s->buf);
- reassemble_patch(s, file_diff, 0, &s->buf);
+ reassemble_patch(s, file_diff, 0, REASSEMBLE_STAGE, &s->buf);
discard_index(s->index);
if (s->mode->apply_for_checkout)
@@ -1574,13 +1633,15 @@ static void apply_patch(struct add_p_state *s, struct file_diff *file_diff)
NULL, 0, NULL, 0))
error(_("'git apply' failed"));
}
- if (read_index_from(s->index, s->index_file, s->r->gitdir) >= 0 &&
- s->index == s->r->index) {
- repo_refresh_and_write_index(s->r, REFRESH_QUIET, 0,
- 1, NULL, NULL, NULL);
- }
+ needs_refresh = 1;
}
+ if (needs_refresh &&
+ read_index_from(s->index, s->index_file, s->r->gitdir) >= 0 &&
+ s->index == s->r->index) {
+ repo_refresh_and_write_index(s->r, REFRESH_QUIET, 0,
+ 1, NULL, NULL, NULL);
+ }
}
static size_t dec_mod(size_t a, size_t m)
@@ -1636,7 +1697,8 @@ static size_t patch_update_file(struct add_p_state *s,
ALLOW_SPLIT = 1 << 5,
ALLOW_EDIT = 1 << 6,
ALLOW_GOTO_PREVIOUS_FILE = 1 << 7,
- ALLOW_GOTO_NEXT_FILE = 1 << 8
+ ALLOW_GOTO_NEXT_FILE = 1 << 8,
+ ALLOW_DISCARD = 1 << 9
} permitted = 0;
if (hunk_index >= file_diff->hunk_nr)
@@ -1722,6 +1784,10 @@ static size_t patch_update_file(struct add_p_state *s,
!file_diff->deleted) {
permitted |= ALLOW_EDIT;
strbuf_addstr(&s->buf, ",e");
+ if (s->mode == &patch_mode_add) {
+ permitted |= ALLOW_DISCARD;
+ strbuf_addstr(&s->buf, ",x");
+ }
}
if (!s->cfg.auto_advance && s->file_diff_nr > 1) {
permitted |= ALLOW_GOTO_NEXT_FILE;
@@ -1750,6 +1816,8 @@ static size_t patch_update_file(struct add_p_state *s,
if (hunk->use != UNDECIDED_HUNK) {
if (hunk->use == USE_HUNK)
hunk_use_decision = _(" (was: y)");
+ else if (hunk->use == DISCARD_HUNK)
+ hunk_use_decision = _(" (was: x)");
else
hunk_use_decision = _(" (was: n)");
}
@@ -1780,6 +1848,13 @@ static size_t patch_update_file(struct add_p_state *s,
} else if (ch == 'n') {
hunk->use = SKIP_HUNK;
goto soft_increment;
+ } else if (ch == 'x') {
+ if (!(permitted & ALLOW_DISCARD))
+ err(s, _("Sorry, cannot discard this hunk"));
+ else {
+ hunk->use = DISCARD_HUNK;
+ goto soft_increment;
+ }
} else if (ch == 'a') {
if (file_diff->hunk_nr) {
for (; hunk_index < file_diff->hunk_nr; hunk_index++) {
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 6e120a4001..0eb813f74c 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -48,8 +48,8 @@ test_expect_success 'unknown command' '
git add -N command &&
git diff command >expect &&
cat >>expect <<-EOF &&
- (1/1) Stage addition [y,n,q,a,d,e,p,P,?]? Unknown command ${SQ}W${SQ} (use ${SQ}?${SQ} for help)
- (1/1) Stage addition [y,n,q,a,d,e,p,P,?]?$SP
+ (1/1) Stage addition [y,n,q,a,d,e,x,p,P,?]? Unknown command ${SQ}W${SQ} (use ${SQ}?${SQ} for help)
+ (1/1) Stage addition [y,n,q,a,d,e,x,p,P,?]?$SP
EOF
git add -p -- command <command >actual 2>&1 &&
test_cmp expect actual
@@ -334,7 +334,7 @@ test_expect_success 'different prompts for mode change/deleted' '
cat >expect <<-\EOF &&
(1/1) Stage deletion [y,n,q,a,d,p,P,?]?
(1/2) Stage mode change [y,n,q,a,d,k,K,j,J,g,/,p,P,?]?
- (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,P,?]?
+ (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,x,p,P,?]?
EOF
test_cmp expect actual.filtered
'
@@ -447,6 +447,24 @@ test_expect_success 'add first line works' '
test_cmp expected-output output
'
+test_expect_success 'add -p discard removes worktree change' '
+ test_when_finished "rm -rf discard-testrepo" &&
+ mkdir discard-testrepo &&
+ (
+ cd discard-testrepo &&
+ git init -b main &&
+ echo clean >discard-me &&
+ git add discard-me &&
+ git commit -m base &&
+ echo extra >>discard-me &&
+ test_write_lines x | git add -p discard-me &&
+ printf "clean\n" >expect &&
+ test_cmp expect discard-me &&
+ git diff --cached >tmp &&
+ test_must_be_empty tmp
+ )
+'
+
test_expect_success 'setup expected' '
cat >expected <<-\EOF
diff --git a/non-empty b/non-empty
@@ -521,13 +539,13 @@ test_expect_success 'split hunk setup' '
test_expect_success 'goto hunk 1 with "g 1"' '
test_when_finished "git reset" &&
tr _ " " >expect <<-EOF &&
- (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,P,?]? + 1: -1,2 +1,3 +15
+ (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,x,p,P,?]? + 1: -1,2 +1,3 +15
_ 2: -2,4 +3,8 +21
go to which hunk? @@ -1,2 +1,3 @@
_10
+15
_20
- (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]?_
EOF
test_write_lines s y g 1 | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -540,7 +558,7 @@ test_expect_success 'goto hunk 1 with "g1"' '
_10
+15
_20
- (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]?_
EOF
test_write_lines s y g1 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -550,11 +568,11 @@ test_expect_success 'goto hunk 1 with "g1"' '
test_expect_success 'navigate to hunk via regex /pattern' '
test_when_finished "git reset" &&
tr _ " " >expect <<-EOF &&
- (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,x,p,P,?]? @@ -1,2 +1,3 @@
_10
+15
_20
- (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]?_
EOF
test_write_lines s y /1,2 | git add -p >actual &&
tail -n 5 <actual >actual.trimmed &&
@@ -567,7 +585,7 @@ test_expect_success 'navigate to hunk via regex / pattern' '
_10
+15
_20
- (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]?_
EOF
test_write_lines s y / 1,2 | git add -p >actual &&
tail -n 4 <actual >actual.trimmed &&
@@ -579,11 +597,11 @@ test_expect_success 'print again the hunk' '
tr _ " " >expect <<-EOF &&
+15
20
- (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? @@ -1,2 +1,3 @@
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]? @@ -1,2 +1,3 @@
10
+15
20
- (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?_
+ (1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]?_
EOF
test_write_lines s y g 1 p | git add -p >actual &&
tail -n 7 <actual >actual.trimmed &&
@@ -595,11 +613,11 @@ test_expect_success TTY 'print again the hunk (PAGER)' '
cat >expect <<-EOF &&
<GREEN>+<RESET><GREEN>15<RESET>
20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]? <RESET>PAGER <CYAN>@@ -1,2 +1,3 @@<RESET>
PAGER 10<RESET>
PAGER <GREEN>+<RESET><GREEN>15<RESET>
PAGER 20<RESET>
- <BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <BOLD;BLUE>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]? <RESET>
EOF
test_write_lines s y g 1 P |
(
@@ -796,21 +814,21 @@ test_expect_success 'colors can be overridden' '
<BLUE>+<RESET><BLUE>new<RESET>
<CYAN> more-context<RESET>
<BLUE>+<RESET><BLUE>another-one<RESET>
- <YELLOW>(1/1) Stage this hunk [y,n,q,a,d,s,e,p,P,?]? <RESET><BOLD>Split into 2 hunks.<RESET>
+ <YELLOW>(1/1) Stage this hunk [y,n,q,a,d,s,e,x,p,P,?]? <RESET><BOLD>Split into 2 hunks.<RESET>
<MAGENTA>@@ -1,3 +1,3 @@<RESET>
<CYAN> context<RESET>
<BOLD>-old<RESET>
<BLUE>+<RESET><BLUE>new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET><MAGENTA>@@ -3 +3,2 @@<RESET>
+ <YELLOW>(1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]? <RESET><MAGENTA>@@ -3 +3,2 @@<RESET>
<CYAN> more-context<RESET>
<BLUE>+<RESET><BLUE>another-one<RESET>
- <YELLOW>(2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,p,P,?]? <RESET><MAGENTA>@@ -1,3 +1,3 @@<RESET>
+ <YELLOW>(2/2) Stage this hunk [y,n,q,a,d,K,J,g,/,e,x,p,P,?]? <RESET><MAGENTA>@@ -1,3 +1,3 @@<RESET>
<CYAN> context<RESET>
<BOLD>-old<RESET>
<BLUE>+new<RESET>
<CYAN> more-context<RESET>
- <YELLOW>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? <RESET>
+ <YELLOW>(1/2) Stage this hunk (was: y) [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]? <RESET>
EOF
test_cmp expect actual
'
@@ -1424,9 +1442,9 @@ test_expect_success 'invalid option s is rejected' '
test_write_lines j s q | git add -p >out &&
sed -ne "s/ @@.*//" -e "s/ \$//" -e "/^(/p" <out >actual &&
cat >expect <<-EOF &&
- (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,s,e,p,P,?]?
- (2/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]? Sorry, cannot split this hunk
- (2/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,p,P,?]?
+ (1/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,s,e,x,p,P,?]?
+ (2/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]? Sorry, cannot split this hunk
+ (2/2) Stage this hunk [y,n,q,a,d,k,K,j,J,g,/,e,x,p,P,?]?
EOF
test_cmp expect actual
'
--
2.43.0
next prev parent reply other threads:[~2026-03-25 7:52 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-25 7:50 [RFC PATCH 0/1] add -p: support discarding hunks Luiz Campos
2026-03-25 7:50 ` Luiz Campos [this message]
2026-03-25 15:44 ` [RFC PATCH 1/1] add -p: support discarding hunks with 'x' D. Ben Knoble
2026-03-25 17:04 ` Luiz Eduardo Campos
2026-03-25 16:24 ` Phillip Wood
2026-03-25 18:38 ` Luiz Eduardo Campos
2026-03-25 16:49 ` Johannes Schindelin
2026-03-25 18:58 ` Luiz Eduardo Campos
2026-03-25 18:03 ` [RFC PATCH 0/1] add -p: support discarding hunks Junio C Hamano
2026-03-25 19:22 ` Luiz Eduardo Campos
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=20260325075055.354709-2-luizedc1@gmail.com \
--to=luizedc1@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
--cc=sagotsky@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.